Improve testing coverage with updates to pcre2test and test files; also get rid

of redundant code in pcre2_match().
This commit is contained in:
Philip.Hazel 2017-04-16 13:03:30 +00:00
parent 87094fac10
commit 202cb2cf41
15 changed files with 1583 additions and 428 deletions

View File

@ -137,6 +137,9 @@ particular when it is serialized.
26. Correct an incorrect cast in pcre2_valid_utf.c 26. Correct an incorrect cast in pcre2_valid_utf.c
27. Update pcre2test, remove some unused code in pcre2_match(), and upgrade the
tests to improve coverage.
Version 10.23 14-February-2017 Version 10.23 14-February-2017
------------------------------ ------------------------------

View File

@ -628,7 +628,7 @@ if (N >= mb->match_frames_top)
if ((newsize / 1024) > mb->heap_limit) if ((newsize / 1024) > mb->heap_limit)
{ {
PCRE2_SIZE maxsize = ((mb->heap_limit * 1024)/frame_size) * frame_size; PCRE2_SIZE maxsize = ((mb->heap_limit * 1024)/frame_size) * frame_size;
if (mb->frame_vector_size == maxsize) return PCRE2_ERROR_HEAPLIMIT; if (mb->frame_vector_size >= maxsize) return PCRE2_ERROR_HEAPLIMIT;
newsize = maxsize; newsize = maxsize;
} }
@ -3058,15 +3058,19 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
Feptr += Lmin; Feptr += Lmin;
break; break;
case OP_ANYBYTE: /* This OP_ANYBYTE case will never be reached because \C gets turned
if (Feptr > mb->end_subject - Lmin) into OP_ALLANY in non-UTF mode. Cut out the code so that coverage
{ reports don't complain about it's never being used. */
SCHECK_PARTIAL();
RRETURN(MATCH_NOMATCH);
}
Feptr += Lmin;
break;
/* case OP_ANYBYTE:
* if (Feptr > mb->end_subject - Lmin)
* {
* SCHECK_PARTIAL();
* RRETURN(MATCH_NOMATCH);
* }
* Feptr += Lmin;
* break;
*/
case OP_ANYNL: case OP_ANYNL:
for (i = 1; i <= Lmin; i++) for (i = 1; i <= Lmin; i++)
{ {
@ -3573,6 +3577,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
switch(fc) switch(fc)
{ {
default: RRETURN(MATCH_NOMATCH); default: RRETURN(MATCH_NOMATCH);
case CHAR_CR: case CHAR_CR:
if (Feptr < mb->end_subject && UCHAR21(Feptr) == CHAR_LF) Feptr++; if (Feptr < mb->end_subject && UCHAR21(Feptr) == CHAR_LF) Feptr++;
break; break;
@ -3700,6 +3705,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
switch(fc) switch(fc)
{ {
default: RRETURN(MATCH_NOMATCH); default: RRETURN(MATCH_NOMATCH);
case CHAR_CR: case CHAR_CR:
if (Feptr < mb->end_subject && *Feptr == CHAR_LF) Feptr++; if (Feptr < mb->end_subject && *Feptr == CHAR_LF) Feptr++;
break; break;
@ -5004,15 +5010,10 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
Lnext_branch = Fecode + GET(Fecode, 1); Lnext_branch = Fecode + GET(Fecode, 1);
if (*Lnext_branch != OP_ALT) break; if (*Lnext_branch != OP_ALT) break;
/* This is never the final branch */ /* This is never the final branch. We do not need to test for MATCH_THEN
here because this code is not used when there is a THEN in the pattern. */
RMATCH(Fecode + PRIV(OP_lengths)[*Fecode], RM1); RMATCH(Fecode + PRIV(OP_lengths)[*Fecode], RM1);
if (rrc == MATCH_THEN)
{
if (mb->verb_ecode_ptr < Lnext_branch &&
(*Fecode == OP_ALT || *Lnext_branch == OP_ALT))
rrc = MATCH_NOMATCH;
}
if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (rrc != MATCH_NOMATCH) RRETURN(rrc);
Fecode = Lnext_branch; Fecode = Lnext_branch;
} }

View File

@ -324,7 +324,7 @@ extern int valid_utf(PCRE2_SPTR8, PCRE2_SIZE, PCRE2_SIZE *);
/* If we have 8-bit support, default to it; if there is also 16-or 32-bit /* If we have 8-bit support, default to it; if there is also 16-or 32-bit
support, it can be selected by a command-line option. If there is no 8-bit support, it can be selected by a command-line option. If there is no 8-bit
support, there must be 16- or 32-bit support, so default to one of them. The support, there must be 16-bit or 32-bit support, so default to one of them. The
config function, JIT stack, contexts, and version string are the same in all config function, JIT stack, contexts, and version string are the same in all
modes, so use the form of the first that is available. */ modes, so use the form of the first that is available. */
@ -336,7 +336,6 @@ modes, so use the form of the first that is available. */
#define PCRE2_REAL_GENERAL_CONTEXT pcre2_real_general_context_8 #define PCRE2_REAL_GENERAL_CONTEXT pcre2_real_general_context_8
#define PCRE2_REAL_COMPILE_CONTEXT pcre2_real_compile_context_8 #define PCRE2_REAL_COMPILE_CONTEXT pcre2_real_compile_context_8
#define PCRE2_REAL_MATCH_CONTEXT pcre2_real_match_context_8 #define PCRE2_REAL_MATCH_CONTEXT pcre2_real_match_context_8
#define VERSION_TYPE PCRE2_UCHAR8
#elif defined SUPPORT_PCRE2_16 #elif defined SUPPORT_PCRE2_16
#define DEFAULT_TEST_MODE PCRE16_MODE #define DEFAULT_TEST_MODE PCRE16_MODE
@ -3725,6 +3724,7 @@ static int
pattern_info(int what, void *where, BOOL unsetok) pattern_info(int what, void *where, BOOL unsetok)
{ {
int rc; int rc;
PCRE2_PATTERN_INFO(rc, compiled_code, what, NULL); /* Exercise the code */
PCRE2_PATTERN_INFO(rc, compiled_code, what, where); PCRE2_PATTERN_INFO(rc, compiled_code, what, where);
if (rc >= 0) return 0; if (rc >= 0) return 0;
if (rc != PCRE2_ERROR_UNSET || !unsetok) if (rc != PCRE2_ERROR_UNSET || !unsetok)
@ -4056,6 +4056,7 @@ if ((pat_patctl.control & (CTL_BINCODE|CTL_FULLBINCODE)) != 0)
if ((pat_patctl.control & CTL_INFO) != 0) if ((pat_patctl.control & CTL_INFO) != 0)
{ {
int rc;
void *nametable; void *nametable;
uint8_t *start_bits; uint8_t *start_bits;
BOOL heap_limit_set, match_limit_set, depth_limit_set; BOOL heap_limit_set, match_limit_set, depth_limit_set;
@ -4064,6 +4065,11 @@ if ((pat_patctl.control & CTL_INFO) != 0)
depth_limit, heap_limit, match_limit, minlength, nameentrysize, namecount, depth_limit, heap_limit, match_limit, minlength, nameentrysize, namecount,
newline_convention; newline_convention;
/* Exercise the error route. */
PCRE2_PATTERN_INFO(rc, compiled_code, 999, NULL);
(void)rc;
/* These info requests may return PCRE2_ERROR_UNSET. */ /* These info requests may return PCRE2_ERROR_UNSET. */
switch(pattern_info(PCRE2_INFO_HEAPLIMIT, &heap_limit, TRUE)) switch(pattern_info(PCRE2_INFO_HEAPLIMIT, &heap_limit, TRUE))
@ -5363,7 +5369,7 @@ return PR_OK;
/************************************************* /*************************************************
* Check match or depth limit * * Check heap, match or depth limit *
*************************************************/ *************************************************/
/* This is used for DFA, normal, and JIT fast matching. For DFA matching it /* This is used for DFA, normal, and JIT fast matching. For DFA matching it
@ -7484,6 +7490,7 @@ return 0;
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
uint32_t temp;
uint32_t yield = 0; uint32_t yield = 0;
uint32_t op = 1; uint32_t op = 1;
BOOL notdone = TRUE; BOOL notdone = TRUE;
@ -7528,6 +7535,20 @@ if (PCRE2_CONFIG(PCRE2_CONFIG_VERSION, NULL) !=
return 1; return 1;
} }
/* Check that bad options are diagnosed. */
if (PCRE2_CONFIG(999, NULL) != PCRE2_ERROR_BADOPTION ||
PCRE2_CONFIG(999, &temp) != PCRE2_ERROR_BADOPTION)
{
fprintf(stderr, "** Error in pcre2_config(): bad option not diagnosed\n");
return 1;
}
/* This configuration option is now obsolete, but running a quick check ensures
that its code is covered. */
(void)PCRE2_CONFIG(PCRE2_CONFIG_STACKRECURSE, &temp);
/* Get buffers from malloc() so that valgrind will check their misuse when /* Get buffers from malloc() so that valgrind will check their misuse when
debugging. They grow automatically when very long lines are read. The 16- debugging. They grow automatically when very long lines are read. The 16-
and 32-bit buffers (pbuffer16, pbuffer32) are obtained only if needed. */ and 32-bit buffers (pbuffer16, pbuffer32) are obtained only if needed. */
@ -7571,32 +7592,45 @@ while (argc > 1 && argv[op][0] == '-' && argv[op][1] != 0)
goto EXIT; goto EXIT;
} }
/* Select operating mode */ /* Select operating mode. Ensure that pcre2_config() is called in 16-bit
and 32-bit modes because that won't happen naturally when 8-bit is also
configured. Also call some other functions that are not otherwise used. This
means that a coverage report won't claim there are uncalled functions. */
if (strcmp(arg, "-8") == 0) if (strcmp(arg, "-8") == 0)
{ {
#ifdef SUPPORT_PCRE2_8 #ifdef SUPPORT_PCRE2_8
test_mode = PCRE8_MODE; test_mode = PCRE8_MODE;
(void)pcre2_set_bsr_8(pat_context8, 999);
(void)pcre2_set_newline_8(pat_context8, 999);
#else #else
fprintf(stderr, fprintf(stderr,
"** This version of PCRE2 was built without 8-bit support\n"); "** This version of PCRE2 was built without 8-bit support\n");
exit(1); exit(1);
#endif #endif
} }
else if (strcmp(arg, "-16") == 0) else if (strcmp(arg, "-16") == 0)
{ {
#ifdef SUPPORT_PCRE2_16 #ifdef SUPPORT_PCRE2_16
test_mode = PCRE16_MODE; test_mode = PCRE16_MODE;
(void)pcre2_config_16(PCRE2_CONFIG_VERSION, NULL);
(void)pcre2_set_bsr_16(pat_context16, 999);
(void)pcre2_set_newline_16(pat_context16, 999);
#else #else
fprintf(stderr, fprintf(stderr,
"** This version of PCRE2 was built without 16-bit support\n"); "** This version of PCRE2 was built without 16-bit support\n");
exit(1); exit(1);
#endif #endif
} }
else if (strcmp(arg, "-32") == 0) else if (strcmp(arg, "-32") == 0)
{ {
#ifdef SUPPORT_PCRE2_32 #ifdef SUPPORT_PCRE2_32
test_mode = PCRE32_MODE; test_mode = PCRE32_MODE;
(void)pcre2_config_32(PCRE2_CONFIG_VERSION, NULL);
(void)pcre2_set_bsr_32(pat_context32, 999);
(void)pcre2_set_newline_32(pat_context32, 999);
#else #else
fprintf(stderr, fprintf(stderr,
"** This version of PCRE2 was built without 32-bit support\n"); "** This version of PCRE2 was built without 32-bit support\n");
@ -7848,7 +7882,13 @@ max_oveccount = DEFAULT_OVECCOUNT;
G(dat_context,BITS) = G(pcre2_match_context_copy_,BITS)(G(default_dat_context,BITS)); \ G(dat_context,BITS) = G(pcre2_match_context_copy_,BITS)(G(default_dat_context,BITS)); \
G(match_data,BITS) = G(pcre2_match_data_create_,BITS)(max_oveccount, G(general_context,BITS)) G(match_data,BITS) = G(pcre2_match_data_create_,BITS)(max_oveccount, G(general_context,BITS))
/* Call the appropriate functions for the current mode. */ #define CONTEXTTESTS \
(void)G(pcre2_set_max_pattern_length_,BITS)(G(pat_context,BITS), 0); \
(void)G(pcre2_set_offset_limit_,BITS)(G(dat_context,BITS), 0); \
(void)G(pcre2_set_recursion_memory_management_,BITS)(G(dat_context,BITS), my_malloc, my_free, NULL)
/* Call the appropriate functions for the current mode, and exercise some
functions that are not otherwise called. */
#ifdef SUPPORT_PCRE2_8 #ifdef SUPPORT_PCRE2_8
#undef BITS #undef BITS
@ -7856,6 +7896,7 @@ max_oveccount = DEFAULT_OVECCOUNT;
if (test_mode == PCRE8_MODE) if (test_mode == PCRE8_MODE)
{ {
CREATECONTEXTS; CREATECONTEXTS;
CONTEXTTESTS;
} }
#endif #endif
@ -7865,6 +7906,7 @@ if (test_mode == PCRE8_MODE)
if (test_mode == PCRE16_MODE) if (test_mode == PCRE16_MODE)
{ {
CREATECONTEXTS; CREATECONTEXTS;
CONTEXTTESTS;
} }
#endif #endif
@ -7874,6 +7916,7 @@ if (test_mode == PCRE16_MODE)
if (test_mode == PCRE32_MODE) if (test_mode == PCRE32_MODE)
{ {
CREATECONTEXTS; CREATECONTEXTS;
CONTEXTTESTS;
} }
#endif #endif

3
testdata/testinput1 vendored
View File

@ -5917,4 +5917,7 @@ ef) x/x,mark
/^(?(?!(a)(*ACCEPT))def|abc)/ /^(?(?!(a)(*ACCEPT))def|abc)/
abc abc
/^(?1)\d{3}(a)/
a123a
# End of testinput1 # End of testinput1

View File

@ -165,4 +165,7 @@
/(|]+){2,2452}/ /(|]+){2,2452}/
(|]+){2,2452} (|]+){2,2452}
/(*LIMIT_HEAP=21)\[(a)]{60}/expand
\[a]{60}
# End of testinput15 # End of testinput15

191
testdata/testinput2 vendored
View File

@ -5054,4 +5054,195 @@ a)"xI
/(?(VERSION>=999)yes|no)^bc/I /(?(VERSION>=999)yes|no)^bc/I
/(*LIMIT_HEAP=0)xxx/I
/\d{0,3}(*:abc)(?C1)xxx/callout_info
# ----------------------------------------------------------------------
# These are a whole pile of tests that touch lines of code that are not
# used by any other tests (at least when these were created).
/^a+?x/i,no_start_optimize,no_auto_possess
\= Expect no match
aaa
/^[^a]{3,}?x/i,no_start_optimize,no_auto_possess
\= Expect no match
bbb
cc
/^X\S/no_start_optimize,no_auto_possess
\= Expect no match
X
/^X\W/no_start_optimize,no_auto_possess
\= Expect no match
X
/^X\H/no_start_optimize,no_auto_possess
\= Expect no match
X
/^X\h/no_start_optimize,no_auto_possess
\= Expect no match
X
/^X\V/no_start_optimize,no_auto_possess
\= Expect no match
X
/^X\v/no_start_optimize,no_auto_possess
\= Expect no match
X
/^X\h/no_start_optimize,no_auto_possess
\= Expect no match
XY
/^X\V/no_start_optimize,no_auto_possess
\= Expect no match
X\n
/^X\v/no_start_optimize,no_auto_possess
\= Expect no match
XX
/^X.+?/s,no_start_optimize,no_auto_possess
\= Expect no match
X
/^X\R+?/no_start_optimize,no_auto_possess
\= Expect no match
XX
/^X\H+?/no_start_optimize,no_auto_possess
\= Expect no match
X
/^X\h+?/no_start_optimize,no_auto_possess
\= Expect no match
X
/^X\V+?/no_start_optimize,no_auto_possess
\= Expect no match
X
X\n
/^X\D+?/no_start_optimize,no_auto_possess
\= Expect no match
X
X9
/^X\S+?/no_start_optimize,no_auto_possess
\= Expect no match
X
X\n
/^X\W+?/no_start_optimize,no_auto_possess
\= Expect no match
X
XX
/^X.+?Z/no_start_optimize,no_auto_possess
\= Expect no match
XY\n
/(*CRLF)^X.+?Z/no_start_optimize,no_auto_possess
\= Expect no match
XY\r\=ps
/^X\R+?Z/no_start_optimize,no_auto_possess
\= Expect no match
X\nX
X\n\r\n
X\n\rY
X\n\nY
X\n\x{0c}Y
/(*BSR_ANYCRLF)^X\R+?Z/no_start_optimize,no_auto_possess
\= Expect no match
X\nX
X\n\r\n
X\n\rY
X\n\nY
X\n\x{0c}Y
/^X\H+?Z/no_start_optimize,no_auto_possess
\= Expect no match
XY\t
XYY
/^X\h+?Z/no_start_optimize,no_auto_possess
\= Expect no match
X\t\t
X\tY
/^X\V+?Z/no_start_optimize,no_auto_possess
\= Expect no match
XY\n
XYY
/^X\v+?Z/no_start_optimize,no_auto_possess
\= Expect no match
X\n\n
X\nY
/^X\D+?Z/no_start_optimize,no_auto_possess
\= Expect no match
XY9
XYY
/^X\d+?Z/no_start_optimize,no_auto_possess
\= Expect no match
X99
X9Y
/^X\S+?Z/no_start_optimize,no_auto_possess
\= Expect no match
XY\n
XYY
/^X\s+?Z/no_start_optimize,no_auto_possess
\= Expect no match
X\n\n
X\nY
/^X\W+?Z/no_start_optimize,no_auto_possess
\= Expect no match
X.A
X++
/^X\w+?Z/no_start_optimize,no_auto_possess
\= Expect no match
Xa.
Xaa
/^X.{1,3}Z/s,no_start_optimize,no_auto_possess
\= Expect no match
Xa.bd
/^X\h+Z/no_start_optimize,no_auto_possess
\= Expect no match
X\t\t
X\tY
/^X\V+Z/no_start_optimize,no_auto_possess
\= Expect no match
XY\n
XYY
/^(X(*THEN)Y|AB){0}(?1)/
ABX
\= Expect no match
XAB
/^(?!A(?C1)B)C/
ABC\=callout_error=1
/^(?(?!A(?C1)B)C)/
ABC\=callout_error=1
# ----------------------------------------------------------------------
# End of testinput2 # End of testinput2

View File

@ -94,4 +94,8 @@
\= Expect no match in 8-bit mode \= Expect no match in 8-bit mode
a\x{100}b a\x{100}b
/^ab\C/utf,no_start_optimize
\= Expect no match - tests \C at end of subject
ab
# End of testinput22 # End of testinput22

13
testdata/testinput4 vendored
View File

@ -1627,6 +1627,11 @@
/[z\x{1f88}]+/i,utf /[z\x{1f88}]+/i,utf
\x{1f88}\x{1f80} \x{1f88}\x{1f80}
# Check a reference with more than one other case
/^(\x{00b5})\1{2}$/i,utf
\x{00b5}\x{039c}\x{03bc}
# Characters with more than one other case; test in classes # Characters with more than one other case; test in classes
/[z\x{00b5}]+/i,utf /[z\x{00b5}]+/i,utf
@ -2288,4 +2293,12 @@
/(?(?=.*b)(?=.*b)\pL|.*c)/ /(?(?=.*b)(?=.*b)\pL|.*c)/
11bb 11bb
/^\x{123}+?$/utf,no_auto_possess
\x{123}\x{123}\x{123}
/^\x{123}+?$/i,utf,no_auto_possess
\x{123}\x{122}\x{123}
\= Expect no match
\x{123}\x{124}\x{123}
# End of testinput4 # End of testinput4

251
testdata/testinput5 vendored
View File

@ -1766,4 +1766,255 @@
//g,utf //g,utf
\=zero_terminate \=zero_terminate
/^(?1)\p{Nd}{3}(a)/
a123a
/\p{Nd}{0,3}[\pL](*:abc)(?C1)xxx/callout_info
# ---------------------------------------------------------------------------
# A bunch of tests that hit lines of code that others do not (at least when
# these were created).
/^[^a]{3,}?x/i,utf,no_start_optimize,no_auto_possess
\= Expect no match
bbb
cc
/^[ac]{3,}?x/i,utf,no_start_optimize,no_auto_possess
\= Expect no match
aaa\x{100}
/^X\X/no_start_optimize,no_auto_possess
\= Expect no match
X
/^X\p{L&}+?/no_start_optimize,no_auto_possess
\= Expect no match
X
/^X\p{L}+?/no_start_optimize,no_auto_possess
\= Expect no match
X
/^X\p{Lu}+?/no_start_optimize,no_auto_possess
\= Expect no match
X
/^X\p{Arabic}+?/no_start_optimize,no_auto_possess
\= Expect no match
X
/^X\p{Xan}+?/ucp,no_start_optimize,no_auto_possess
\= Expect no match
X
/^X\s+?/ucp,no_start_optimize,no_auto_possess
\= Expect no match
X
XX
/^X\S+?/ucp,no_start_optimize,no_auto_possess
XX
\= Expect no match
X
/^X\w+?/ucp,no_start_optimize,no_auto_possess
\= Expect no match
X
/^X[^\x{b5}]+?/i,utf,no_start_optimize,no_auto_possess
\= Expect no match
X
/^X[\x{b5}]+?/i,utf,no_start_optimize,no_auto_possess
\= Expect no match
X
/^X\p{Xuc}+?/utf,no_start_optimize,no_auto_possess
\= Expect no match
X
/^X.+?Z/s,utf,no_start_optimize,no_auto_possess
\= Expect no match
X
/^X\R+?/utf,no_start_optimize,no_auto_possess
\= Expect no match
X
/^X\H+?/utf,no_start_optimize,no_auto_possess
\= Expect no match
X
/^X\V+?/utf,no_start_optimize,no_auto_possess
\= Expect no match
X
/^X\s+?/utf,no_start_optimize,no_auto_possess
\= Expect no match
X
XX
/^X\S+?/utf,no_start_optimize,no_auto_possess
\= Expect no match
X
/^X\p{Any}{1,3}?Z/s,no_start_optimize,no_auto_possess
XYYYZ
\= Expect no match
XY
XYY
XYYY
XYYYYZ
/^X\p{L&}{1,3}?Z/s,no_start_optimize,no_auto_possess
\= Expect no match
XY
XY!
/^X\p{L}{1,3}?Z/s,no_start_optimize,no_auto_possess
\= Expect no match
XY
XY!
/^X\p{Lu}{1,3}?Z/s,no_start_optimize,no_auto_possess
\= Expect no match
XY
XY!
/^X\P{Han}{1,3}?Z/s,utf,no_start_optimize,no_auto_possess
\= Expect no match
XY
XY!
XY\x{2f00}!
/^X\p{Xan}{1,3}?Z/s,no_start_optimize,no_auto_possess
\= Expect no match
XY
XY!
/^X\p{Xsp}{1,3}?Z/s,no_start_optimize,no_auto_possess
\= Expect no match
X\n
X\n!
X\n\n!
/^X\P{Xsp}{1,3}?Z/s,no_start_optimize,no_auto_possess
\= Expect no match
XYY\n
/^X\p{Xwd}{1,3}?Z/s,no_start_optimize,no_auto_possess
\= Expect no match
XY
XY!
XYY!
/^X\x{b5}+?Z/i,utf,no_start_optimize,no_auto_possess
\= Expect no match
X
X\x{b5}
X\x{b5}\x{b5}Y
/^X\p{Xuc}+?Z/utf,no_start_optimize,no_auto_possess
\= Expect no match
X
X$
X@@Y
/(*CRLF)^X.+?Z/utf,no_start_optimize,no_auto_possess
\= Expect partial match
XYY\r\=ph
\= Expect no match
X
/^X.+?Z/s,utf,no_start_optimize,no_auto_possess
\= Expect no match
X
XYY
/^X\R+?Z/utf,no_start_optimize,no_auto_possess
\= Expect no match
X\nX
X\n\rX
X\n\r\nX
X\n\n
X\n\x{0c}
/(*BSR_ANYCRLF)^X\R+?Z/utf,no_start_optimize,no_auto_possess
\= Expect no match
X\nX
X\n\rX
X\n\r\nX
X\n\n
X\n\x{0c}
/^X\H+?Z/utf,no_start_optimize,no_auto_possess
\= Expect no match
XY\t
XYY
/^X\h+?Z/utf,no_start_optimize,no_auto_possess
\= Expect no match
X\t\t
X\tY
/^X\V+?Z/utf,no_start_optimize,no_auto_possess
\= Expect no match
XY\n
XYY
/^X\v+?Z/utf,no_start_optimize,no_auto_possess
\= Expect no match
X\n\n
X\nY
/^X\D+?Z/utf,no_start_optimize,no_auto_possess
\= Expect no match
XY9
XYY
/^X\d+?Z/utf,no_start_optimize,no_auto_possess
\= Expect no match
X99
X9Y
/^X\S+?Z/utf,no_start_optimize,no_auto_possess
\= Expect no match
XY\n
XYY
/^X\s+?Z/utf,no_start_optimize,no_auto_possess
\= Expect no match
X\n\n
X\nY
/^X\W+?Z/utf,no_start_optimize,no_auto_possess
\= Expect no match
X.A
X++
/^X\p{L&}{1,3}Z/no_start_optimize,no_auto_possess
\= Expect no match
XY
XY!
/^X\p{L}{1,3}Z/no_start_optimize,no_auto_possess
\= Expect no match
XY
/^X\p{Xan}{1,3}Z/no_start_optimize,no_auto_possess
\= Expect no match
XY
/^X\P{Xsp}{1,3}Z/no_start_optimize,no_auto_possess
\= Expect no match
XYY
/^X\p{Xuc}+Z/utf,no_start_optimize,no_auto_possess
\= Expect no match
X$
# ---------------------------------------------------------------------------
# End of testinput5 # End of testinput5

View File

@ -9487,4 +9487,9 @@ No match
0: abc 0: abc
1: a 1: a
/^(?1)\d{3}(a)/
a123a
0: a123a
1: a
# End of testinput1 # End of testinput1

View File

@ -400,4 +400,8 @@ No match
0: 0:
1: 1:
/(*LIMIT_HEAP=21)\[(a)]{60}/expand
\[a]{60}
Failed: error -63: heap limit exceeded
# End of testinput15 # End of testinput15

266
testdata/testoutput2 vendored
View File

@ -15607,6 +15607,272 @@ Capturing subpattern count = 0
Last code unit = 'c' Last code unit = 'c'
Subject length lower bound = 4 Subject length lower bound = 4
/(*LIMIT_HEAP=0)xxx/I
Capturing subpattern count = 0
Heap limit = 0
First code unit = 'x'
Last code unit = 'x'
Subject length lower bound = 3
/\d{0,3}(*:abc)(?C1)xxx/callout_info
Callout 1 x
# ----------------------------------------------------------------------
# These are a whole pile of tests that touch lines of code that are not
# used by any other tests (at least when these were created).
/^a+?x/i,no_start_optimize,no_auto_possess
\= Expect no match
aaa
No match
/^[^a]{3,}?x/i,no_start_optimize,no_auto_possess
\= Expect no match
bbb
No match
cc
No match
/^X\S/no_start_optimize,no_auto_possess
\= Expect no match
X
No match
/^X\W/no_start_optimize,no_auto_possess
\= Expect no match
X
No match
/^X\H/no_start_optimize,no_auto_possess
\= Expect no match
X
No match
/^X\h/no_start_optimize,no_auto_possess
\= Expect no match
X
No match
/^X\V/no_start_optimize,no_auto_possess
\= Expect no match
X
No match
/^X\v/no_start_optimize,no_auto_possess
\= Expect no match
X
No match
/^X\h/no_start_optimize,no_auto_possess
\= Expect no match
XY
No match
/^X\V/no_start_optimize,no_auto_possess
\= Expect no match
X\n
No match
/^X\v/no_start_optimize,no_auto_possess
\= Expect no match
XX
No match
/^X.+?/s,no_start_optimize,no_auto_possess
\= Expect no match
X
No match
/^X\R+?/no_start_optimize,no_auto_possess
\= Expect no match
XX
No match
/^X\H+?/no_start_optimize,no_auto_possess
\= Expect no match
X
No match
/^X\h+?/no_start_optimize,no_auto_possess
\= Expect no match
X
No match
/^X\V+?/no_start_optimize,no_auto_possess
\= Expect no match
X
No match
X\n
No match
/^X\D+?/no_start_optimize,no_auto_possess
\= Expect no match
X
No match
X9
No match
/^X\S+?/no_start_optimize,no_auto_possess
\= Expect no match
X
No match
X\n
No match
/^X\W+?/no_start_optimize,no_auto_possess
\= Expect no match
X
No match
XX
No match
/^X.+?Z/no_start_optimize,no_auto_possess
\= Expect no match
XY\n
No match
/(*CRLF)^X.+?Z/no_start_optimize,no_auto_possess
\= Expect no match
XY\r\=ps
Partial match: XY\x0d
/^X\R+?Z/no_start_optimize,no_auto_possess
\= Expect no match
X\nX
No match
X\n\r\n
No match
X\n\rY
No match
X\n\nY
No match
X\n\x{0c}Y
No match
/(*BSR_ANYCRLF)^X\R+?Z/no_start_optimize,no_auto_possess
\= Expect no match
X\nX
No match
X\n\r\n
No match
X\n\rY
No match
X\n\nY
No match
X\n\x{0c}Y
No match
/^X\H+?Z/no_start_optimize,no_auto_possess
\= Expect no match
XY\t
No match
XYY
No match
/^X\h+?Z/no_start_optimize,no_auto_possess
\= Expect no match
X\t\t
No match
X\tY
No match
/^X\V+?Z/no_start_optimize,no_auto_possess
\= Expect no match
XY\n
No match
XYY
No match
/^X\v+?Z/no_start_optimize,no_auto_possess
\= Expect no match
X\n\n
No match
X\nY
No match
/^X\D+?Z/no_start_optimize,no_auto_possess
\= Expect no match
XY9
No match
XYY
No match
/^X\d+?Z/no_start_optimize,no_auto_possess
\= Expect no match
X99
No match
X9Y
No match
/^X\S+?Z/no_start_optimize,no_auto_possess
\= Expect no match
XY\n
No match
XYY
No match
/^X\s+?Z/no_start_optimize,no_auto_possess
\= Expect no match
X\n\n
No match
X\nY
No match
/^X\W+?Z/no_start_optimize,no_auto_possess
\= Expect no match
X.A
No match
X++
No match
/^X\w+?Z/no_start_optimize,no_auto_possess
\= Expect no match
Xa.
No match
Xaa
No match
/^X.{1,3}Z/s,no_start_optimize,no_auto_possess
\= Expect no match
Xa.bd
No match
/^X\h+Z/no_start_optimize,no_auto_possess
\= Expect no match
X\t\t
No match
X\tY
No match
/^X\V+Z/no_start_optimize,no_auto_possess
\= Expect no match
XY\n
No match
XYY
No match
/^(X(*THEN)Y|AB){0}(?1)/
ABX
0: AB
\= Expect no match
XAB
No match
/^(?!A(?C1)B)C/
ABC\=callout_error=1
--->ABC
1 ^^ B
Failed: error -37: callout error code
/^(?(?!A(?C1)B)C)/
ABC\=callout_error=1
--->ABC
1 ^^ B
Failed: error -37: callout error code
# ----------------------------------------------------------------------
# End of testinput2 # End of testinput2
Error -64: PCRE2_ERROR_BADDATA (unknown error number) Error -64: PCRE2_ERROR_BADDATA (unknown error number)
Error -62: bad serialized data Error -62: bad serialized data

View File

@ -168,4 +168,9 @@ No match
a\x{100}b a\x{100}b
No match No match
/^ab\C/utf,no_start_optimize
\= Expect no match - tests \C at end of subject
ab
No match
# End of testinput22 # End of testinput22

18
testdata/testoutput4 vendored
View File

@ -2716,6 +2716,13 @@ No match
\x{1f88}\x{1f80} \x{1f88}\x{1f80}
0: \x{1f88}\x{1f80} 0: \x{1f88}\x{1f80}
# Check a reference with more than one other case
/^(\x{00b5})\1{2}$/i,utf
\x{00b5}\x{039c}\x{03bc}
0: \x{b5}\x{39c}\x{3bc}
1: \x{b5}
# Characters with more than one other case; test in classes # Characters with more than one other case; test in classes
/[z\x{00b5}]+/i,utf /[z\x{00b5}]+/i,utf
@ -3711,4 +3718,15 @@ No match
11bb 11bb
0: b 0: b
/^\x{123}+?$/utf,no_auto_possess
\x{123}\x{123}\x{123}
0: \x{123}\x{123}\x{123}
/^\x{123}+?$/i,utf,no_auto_possess
\x{123}\x{122}\x{123}
0: \x{123}\x{122}\x{123}
\= Expect no match
\x{123}\x{124}\x{123}
No match
# End of testinput4 # End of testinput4

345
testdata/testoutput5 vendored
View File

@ -4236,4 +4236,349 @@ Failed: error 125 at offset 2: lookbehind assertion is not fixed length
\=zero_terminate \=zero_terminate
0: 0:
/^(?1)\p{Nd}{3}(a)/
a123a
0: a123a
1: a
/\p{Nd}{0,3}[\pL](*:abc)(?C1)xxx/callout_info
Callout 1 x
# ---------------------------------------------------------------------------
# A bunch of tests that hit lines of code that others do not (at least when
# these were created).
/^[^a]{3,}?x/i,utf,no_start_optimize,no_auto_possess
\= Expect no match
bbb
No match
cc
No match
/^[ac]{3,}?x/i,utf,no_start_optimize,no_auto_possess
\= Expect no match
aaa\x{100}
No match
/^X\X/no_start_optimize,no_auto_possess
\= Expect no match
X
No match
/^X\p{L&}+?/no_start_optimize,no_auto_possess
\= Expect no match
X
No match
/^X\p{L}+?/no_start_optimize,no_auto_possess
\= Expect no match
X
No match
/^X\p{Lu}+?/no_start_optimize,no_auto_possess
\= Expect no match
X
No match
/^X\p{Arabic}+?/no_start_optimize,no_auto_possess
\= Expect no match
X
No match
/^X\p{Xan}+?/ucp,no_start_optimize,no_auto_possess
\= Expect no match
X
No match
/^X\s+?/ucp,no_start_optimize,no_auto_possess
\= Expect no match
X
No match
XX
No match
/^X\S+?/ucp,no_start_optimize,no_auto_possess
XX
0: XX
\= Expect no match
X
No match
/^X\w+?/ucp,no_start_optimize,no_auto_possess
\= Expect no match
X
No match
/^X[^\x{b5}]+?/i,utf,no_start_optimize,no_auto_possess
\= Expect no match
X
No match
/^X[\x{b5}]+?/i,utf,no_start_optimize,no_auto_possess
\= Expect no match
X
No match
/^X\p{Xuc}+?/utf,no_start_optimize,no_auto_possess
\= Expect no match
X
No match
/^X.+?Z/s,utf,no_start_optimize,no_auto_possess
\= Expect no match
X
No match
/^X\R+?/utf,no_start_optimize,no_auto_possess
\= Expect no match
X
No match
/^X\H+?/utf,no_start_optimize,no_auto_possess
\= Expect no match
X
No match
/^X\V+?/utf,no_start_optimize,no_auto_possess
\= Expect no match
X
No match
/^X\s+?/utf,no_start_optimize,no_auto_possess
\= Expect no match
X
No match
XX
No match
/^X\S+?/utf,no_start_optimize,no_auto_possess
\= Expect no match
X
No match
/^X\p{Any}{1,3}?Z/s,no_start_optimize,no_auto_possess
XYYYZ
0: XYYYZ
\= Expect no match
XY
No match
XYY
No match
XYYY
No match
XYYYYZ
No match
/^X\p{L&}{1,3}?Z/s,no_start_optimize,no_auto_possess
\= Expect no match
XY
No match
XY!
No match
/^X\p{L}{1,3}?Z/s,no_start_optimize,no_auto_possess
\= Expect no match
XY
No match
XY!
No match
/^X\p{Lu}{1,3}?Z/s,no_start_optimize,no_auto_possess
\= Expect no match
XY
No match
XY!
No match
/^X\P{Han}{1,3}?Z/s,utf,no_start_optimize,no_auto_possess
\= Expect no match
XY
No match
XY!
No match
XY\x{2f00}!
No match
/^X\p{Xan}{1,3}?Z/s,no_start_optimize,no_auto_possess
\= Expect no match
XY
No match
XY!
No match
/^X\p{Xsp}{1,3}?Z/s,no_start_optimize,no_auto_possess
\= Expect no match
X\n
No match
X\n!
No match
X\n\n!
No match
/^X\P{Xsp}{1,3}?Z/s,no_start_optimize,no_auto_possess
\= Expect no match
XYY\n
No match
/^X\p{Xwd}{1,3}?Z/s,no_start_optimize,no_auto_possess
\= Expect no match
XY
No match
XY!
No match
XYY!
No match
/^X\x{b5}+?Z/i,utf,no_start_optimize,no_auto_possess
\= Expect no match
X
No match
X\x{b5}
No match
X\x{b5}\x{b5}Y
No match
/^X\p{Xuc}+?Z/utf,no_start_optimize,no_auto_possess
\= Expect no match
X
No match
X$
No match
X@@Y
No match
/(*CRLF)^X.+?Z/utf,no_start_optimize,no_auto_possess
\= Expect partial match
XYY\r\=ph
Partial match: XYY\x{0d}
\= Expect no match
X
No match
/^X.+?Z/s,utf,no_start_optimize,no_auto_possess
\= Expect no match
X
No match
XYY
No match
/^X\R+?Z/utf,no_start_optimize,no_auto_possess
\= Expect no match
X\nX
No match
X\n\rX
No match
X\n\r\nX
No match
X\n\n
No match
X\n\x{0c}
No match
/(*BSR_ANYCRLF)^X\R+?Z/utf,no_start_optimize,no_auto_possess
\= Expect no match
X\nX
No match
X\n\rX
No match
X\n\r\nX
No match
X\n\n
No match
X\n\x{0c}
No match
/^X\H+?Z/utf,no_start_optimize,no_auto_possess
\= Expect no match
XY\t
No match
XYY
No match
/^X\h+?Z/utf,no_start_optimize,no_auto_possess
\= Expect no match
X\t\t
No match
X\tY
No match
/^X\V+?Z/utf,no_start_optimize,no_auto_possess
\= Expect no match
XY\n
No match
XYY
No match
/^X\v+?Z/utf,no_start_optimize,no_auto_possess
\= Expect no match
X\n\n
No match
X\nY
No match
/^X\D+?Z/utf,no_start_optimize,no_auto_possess
\= Expect no match
XY9
No match
XYY
No match
/^X\d+?Z/utf,no_start_optimize,no_auto_possess
\= Expect no match
X99
No match
X9Y
No match
/^X\S+?Z/utf,no_start_optimize,no_auto_possess
\= Expect no match
XY\n
No match
XYY
No match
/^X\s+?Z/utf,no_start_optimize,no_auto_possess
\= Expect no match
X\n\n
No match
X\nY
No match
/^X\W+?Z/utf,no_start_optimize,no_auto_possess
\= Expect no match
X.A
No match
X++
No match
/^X\p{L&}{1,3}Z/no_start_optimize,no_auto_possess
\= Expect no match
XY
No match
XY!
No match
/^X\p{L}{1,3}Z/no_start_optimize,no_auto_possess
\= Expect no match
XY
No match
/^X\p{Xan}{1,3}Z/no_start_optimize,no_auto_possess
\= Expect no match
XY
No match
/^X\P{Xsp}{1,3}Z/no_start_optimize,no_auto_possess
\= Expect no match
XYY
No match
/^X\p{Xuc}+Z/utf,no_start_optimize,no_auto_possess
\= Expect no match
X$
No match
# ---------------------------------------------------------------------------
# End of testinput5 # End of testinput5