@@ -3493,7 +3493,7 @@ uint8_t *nptr;
34933493
34943494for (i = 0 ; i < MAXCPYGET && dat_datctl .copy_numbers [i ] >= 0 ; i ++ )
34953495 {
3496- int rc ;
3496+ int rc , rc2 ;
34973497 PCRE2_SIZE length , length2 ;
34983498 PCRE2_UCHAR copybuffer [256 ];
34993499 uint32_t n = (uint32_t )(dat_datctl .copy_numbers [i ]);
@@ -3506,29 +3506,29 @@ for (i = 0; i < MAXCPYGET && dat_datctl.copy_numbers[i] >= 0; i++)
35063506 }
35073507 else
35083508 {
3509- rc = pcre2_substring_length_bynumber (match_data , n , & length2 );
3510- if (rc < 0 )
3511- {
3512- fprintf (outfile , "Get substring %d length failed (%d): " , n , rc );
3513- if (!print_error_message (rc , "" , "\n" )) return FALSE;
3514- }
3515- else if (length2 != length )
3516- {
3517- fprintf (outfile , "Mismatched substring lengths: %"
3518- SIZ_FORM " %" SIZ_FORM "\n" , length , length2 );
3519- }
35203509 fprintf (outfile , "%2dC " , n );
35213510 pchars (copybuffer , length , utf , outfile );
35223511 fprintf (outfile , " (%" SIZ_FORM ")\n" , length );
35233512 }
3513+ rc2 = pcre2_substring_length_bynumber (match_data , n , & length2 );
3514+ if (rc2 < 0 )
3515+ {
3516+ fprintf (outfile , "Get substring %d length failed (%d): " , n , rc2 );
3517+ if (!print_error_message (rc2 , "" , "\n" )) return FALSE;
3518+ }
3519+ else if (rc >= 0 && length2 != length )
3520+ {
3521+ fprintf (outfile , "Mismatched substring lengths: %"
3522+ SIZ_FORM " %" SIZ_FORM "\n" , length , length2 );
3523+ }
35243524 }
35253525
35263526/* Test copy strings by name */
35273527
35283528nptr = dat_datctl .copy_names ;
35293529for (;;)
35303530 {
3531- int rc ;
3531+ int rc , rc2 ;
35323532 int groupnumber ;
35333533 PCRE2_SIZE length , length2 ;
35343534 PCRE2_UCHAR copybuffer [256 ];
@@ -3564,23 +3564,23 @@ for (;;)
35643564 }
35653565 else
35663566 {
3567- rc = pcre2_substring_length_byname (match_data , pbuffer , & length2 );
3568- if (rc < 0 )
3569- {
3570- fprintf (outfile , "Get substring \"%s\" length failed (%d): " , nptr , rc );
3571- if (!print_error_message (rc , "" , "\n" )) return FALSE;
3572- }
3573- else if (length2 != length )
3574- {
3575- fprintf (outfile , "Mismatched substring lengths: %"
3576- SIZ_FORM " %" SIZ_FORM "\n" , length , length2 );
3577- }
35783567 fprintf (outfile , " C " );
35793568 pchars (copybuffer , length , utf , outfile );
35803569 fprintf (outfile , " (%" SIZ_FORM ") %s" , length , nptr );
35813570 if (groupnumber >= 0 ) fprintf (outfile , " (group %d)\n" , groupnumber );
35823571 else fprintf (outfile , " (non-unique)\n" );
35833572 }
3573+ rc2 = pcre2_substring_length_byname (match_data , pbuffer , & length2 );
3574+ if (rc2 < 0 )
3575+ {
3576+ fprintf (outfile , "Get substring \"%s\" length failed (%d): " , nptr , rc2 );
3577+ if (!print_error_message (rc2 , "" , "\n" )) return FALSE;
3578+ }
3579+ else if (rc >= 0 && length2 != length )
3580+ {
3581+ fprintf (outfile , "Mismatched substring lengths: %"
3582+ SIZ_FORM " %" SIZ_FORM "\n" , length , length2 );
3583+ }
35843584 nptr += namelen + 1 ;
35853585 }
35863586
@@ -5441,6 +5441,7 @@ unittest(void)
54415441int rc ;
54425442uint32_t uval ;
54435443PCRE2_SIZE sizeval ;
5444+ PCRE2_UCHAR * sptrval ;
54445445const char * failure = NULL ;
54455446pcre2_general_context * test_gen_context = NULL , * test_gen_context_copy = NULL ;
54465447pcre2_compile_context * test_pat_context = NULL , * test_pat_context_copy = NULL ;
@@ -5454,6 +5455,13 @@ PCRE2_UCHAR callout_int_pattern[] = {
54545455PCRE2_UCHAR callout_str_pattern [] = {
54555456 CHAR_LEFT_PARENTHESIS , CHAR_QUESTION_MARK , CHAR_C , CHAR_QUOTATION_MARK ,
54565457 CHAR_Z , CHAR_QUOTATION_MARK , CHAR_RIGHT_PARENTHESIS , 0 };
5458+ PCRE2_UCHAR capture_pattern [] = {
5459+ CHAR_A , CHAR_LEFT_PARENTHESIS , CHAR_QUESTION_MARK , CHAR_LESS_THAN_SIGN ,
5460+ CHAR_N , CHAR_GREATER_THAN_SIGN , CHAR_DOT , CHAR_ASTERISK ,
5461+ CHAR_RIGHT_PARENTHESIS , CHAR_Z , 0 };
5462+ PCRE2_UCHAR subject_abcz [] = {
5463+ CHAR_A , CHAR_B , CHAR_C , CHAR_Z , 0 };
5464+ PCRE2_UCHAR name_n [] = { CHAR_N , 0 };
54575465#ifdef BITOTHER
54585466G (pcre2_code_ ,BITOTHER ) * bitother_code = NULL ;
54595467G (PCRE2_ ,G (UCHAR ,BITOTHER )) bitother_pattern [ ] = { CHAR_A , CHAR_B , CHAR_C , 0 };
@@ -5467,6 +5475,9 @@ regex_t test_preg;
54675475#endif
54685476void * invalid_code = NULL ;
54695477const uint8_t * test_tables = NULL ;
5478+ PCRE2_UCHAR copy_buf [64 ];
5479+ PCRE2_UCHAR * * stringlist ;
5480+ PCRE2_SIZE * lengthslist ;
54705481
54715482#if PCRE2_CODE_UNIT_WIDTH == 8
54725483memset (& test_preg , 0 , sizeof (test_preg ));
@@ -5864,6 +5875,109 @@ errorcode = -123;
58645875rc = pcre2_callout_enumerate (test_compiled_code , callout_enumerate_function_fail , & errorcode );
58655876ASSERT (rc == -123 , "pcre2_callout_enumerate(fail)" );
58665877
5878+ /* ---------------------- Substring functions ------------------------------ */
5879+
5880+ /* Must handle NULL without crashing. */
5881+ pcre2_substring_free (NULL );
5882+ pcre2_substring_list_free (NULL );
5883+
5884+ pcre2_code_free (test_compiled_code );
5885+ test_compiled_code = pcre2_compile (capture_pattern , PCRE2_ZERO_TERMINATED ,
5886+ 0 , & errorcode , & erroroffset , NULL );
5887+ ASSERT (test_compiled_code != NULL , "test pattern compilation" );
5888+
5889+ pcre2_match_data_free (test_match_data );
5890+ test_match_data = pcre2_match_data_create_from_pattern (
5891+ test_compiled_code , test_gen_context );
5892+ ASSERT (test_match_data != NULL , "pcre2_match_data_create()" );
5893+
5894+ rc = pcre2_match (test_compiled_code , subject_abcz , PCRE2_ZERO_TERMINATED , 0 ,
5895+ 0 , test_match_data , NULL );
5896+ ASSERT (rc == 2 , "pcre2_match()" );
5897+
5898+ /* Test the functions with insufficient buffer size. It hardly seems worth
5899+ adding controls to the pcre2test input file format to exercise this case. */
5900+
5901+ sizeval = 2 ;
5902+ rc = pcre2_substring_copy_byname (test_match_data , name_n , copy_buf , & sizeval );
5903+ ASSERT (rc == PCRE2_ERROR_NOMEMORY && sizeval == 2 , "pcre2_substring_copy_byname(small buffer)" );
5904+ sizeval = 3 ;
5905+ rc = pcre2_substring_copy_byname (test_match_data , name_n , copy_buf , & sizeval );
5906+ ASSERT (rc == 0 && sizeval == 2 , "pcre2_substring_copy_byname(small buffer)" );
5907+ sizeval = 4 ;
5908+ rc = pcre2_substring_copy_byname (test_match_data , name_n , copy_buf , & sizeval );
5909+ ASSERT (rc == 0 && sizeval == 2 , "pcre2_substring_copy_byname(small buffer)" );
5910+
5911+ sizeval = 2 ;
5912+ rc = pcre2_substring_copy_bynumber (test_match_data , 1 , copy_buf , & sizeval );
5913+ ASSERT (rc == PCRE2_ERROR_NOMEMORY && sizeval == 2 , "pcre2_substring_copy_bynumber(small buffer)" );
5914+ sizeval = 3 ;
5915+ rc = pcre2_substring_copy_bynumber (test_match_data , 1 , copy_buf , & sizeval );
5916+ ASSERT (rc == 0 && sizeval == 2 , "pcre2_substring_copy_bynumber(small buffer)" );
5917+
5918+ mallocs_until_failure = 0 ;
5919+
5920+ sizeval = 0 ;
5921+ sptrval = NULL ;
5922+ rc = pcre2_substring_get_byname (test_match_data , name_n , & sptrval , & sizeval );
5923+ ASSERT (rc == PCRE2_ERROR_NOMEMORY && sptrval == NULL , "pcre2_substring_get_byname(small buffer)" );
5924+
5925+ sizeval = 0 ;
5926+ rc = pcre2_substring_get_bynumber (test_match_data , 1 , & sptrval , & sizeval );
5927+ ASSERT (rc == PCRE2_ERROR_NOMEMORY && sptrval == NULL , "pcre2_substring_get_bynumber(small buffer)" );
5928+
5929+ mallocs_until_failure = INT_MAX ;
5930+
5931+ /* Test some unusual conditions, for which again it doesn't seem worth adding
5932+ pcre2test controls. */
5933+
5934+ sizeval = 0 ;
5935+ rc = pcre2_substring_length_bynumber (test_match_data , 1 , & sizeval );
5936+ ASSERT (rc == 0 && sizeval == 2 , "pcre2_substring_length_bynumber()" );
5937+ rc = pcre2_substring_length_bynumber (test_match_data , 1 , NULL );
5938+ ASSERT (rc == 0 , "pcre2_substring_length_bynumber()" );
5939+
5940+ sizeval = 0 ;
5941+ rc = pcre2_substring_length_byname (test_match_data , name_n , & sizeval );
5942+ ASSERT (rc == 0 && sizeval == 2 , "pcre2_substring_length_byname()" );
5943+ rc = pcre2_substring_length_byname (test_match_data , name_n , NULL );
5944+ ASSERT (rc == 0 , "pcre2_substring_length_byname()" );
5945+
5946+ /* Test pcre2_substring_list_get() with some NULL inputs. */
5947+
5948+ rc = pcre2_substring_list_get (test_match_data , & stringlist , & lengthslist );
5949+ ASSERT (rc == 0 && stringlist != NULL && lengthslist != NULL , "pcre2_substring_list_get()" );
5950+ pcre2_substring_list_free (stringlist );
5951+
5952+ stringlist = NULL ;
5953+ rc = pcre2_substring_list_get (test_match_data , & stringlist , NULL );
5954+ ASSERT (rc == 0 && stringlist != NULL , "pcre2_substring_list_get()" );
5955+ pcre2_substring_list_free (stringlist );
5956+
5957+ mallocs_until_failure = 0 ;
5958+
5959+ stringlist = NULL ;
5960+ rc = pcre2_substring_list_get (test_match_data , & stringlist , & lengthslist );
5961+ ASSERT (rc == PCRE2_ERROR_NOMEMORY && stringlist == NULL , "pcre2_substring_list_get()" );
5962+
5963+ mallocs_until_failure = INT_MAX ;
5964+
5965+ /* Test after an unsuccessful match. */
5966+
5967+ rc = pcre2_match (test_compiled_code , subject_abcz , PCRE2_ZERO_TERMINATED , 2 ,
5968+ 0 , test_match_data , NULL );
5969+ ASSERT (rc == PCRE2_ERROR_NOMATCH , "pcre2_match()" );
5970+
5971+ sizeval = 4 ;
5972+ rc = pcre2_substring_copy_byname (test_match_data , name_n , copy_buf , & sizeval );
5973+ ASSERT (rc == PCRE2_ERROR_NOMATCH , "pcre2_substring_copy_byname(no match)" );
5974+ rc = pcre2_substring_copy_bynumber (test_match_data , 1 , copy_buf , & sizeval );
5975+ ASSERT (rc == PCRE2_ERROR_NOMATCH , "pcre2_substring_copy_bynumber(no match)" );
5976+ rc = pcre2_substring_get_byname (test_match_data , name_n , & sptrval , & sizeval );
5977+ ASSERT (rc == PCRE2_ERROR_NOMATCH && sptrval == NULL , "pcre2_substring_get_byname(no match)" );
5978+ rc = pcre2_substring_get_bynumber (test_match_data , 1 , & sptrval , & sizeval );
5979+ ASSERT (rc == PCRE2_ERROR_NOMATCH && sptrval == NULL , "pcre2_substring_get_bynumber(no match)" );
5980+
58675981/* ------------------------------------------------------------------------- */
58685982
58695983#undef ASSERT
0 commit comments