diff --git a/ChangeLog b/ChangeLog index ae6f568..8bf26c4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -133,6 +133,9 @@ offsets in the pattern. 35. Error messages for syntax errors in *LIMIT_MATCH and *LIMIT_RECURSION now give the right offset instead of zero. +36. The JIT compiler should not check repeats after a {0,1} repeat byte code. +This issue was found by Karl Skomski with a custom LLVM fuzzer. + Version 10.20 30-June-2015 -------------------------- diff --git a/src/pcre2_jit_compile.c b/src/pcre2_jit_compile.c index bd4f0e0..d72112b 100644 --- a/src/pcre2_jit_compile.c +++ b/src/pcre2_jit_compile.c @@ -1281,6 +1281,7 @@ PCRE2_SPTR alternative; PCRE2_SPTR end = NULL; int private_data_ptr = *private_data_start; int space, size, bracketlen; +BOOL repeat_check = TRUE; while (cc < ccend) { @@ -1290,7 +1291,8 @@ while (cc < ccend) if (private_data_ptr > SLJIT_MAX_LOCAL_SIZE) break; - if (*cc == OP_ONCE || *cc == OP_ONCE_NC || *cc == OP_BRA || *cc == OP_CBRA || *cc == OP_COND) + if (repeat_check && (*cc == OP_ONCE || *cc == OP_ONCE_NC || *cc == OP_BRA || *cc == OP_CBRA || *cc == OP_COND)) + { if (detect_repeat(common, cc)) { /* These brackets are converted to repeats, so no global @@ -1298,6 +1300,8 @@ while (cc < ccend) if (cc >= end) end = bracketend(cc); } + } + repeat_check = TRUE; switch(*cc) { @@ -1353,6 +1357,13 @@ while (cc < ccend) bracketlen = 1 + LINK_SIZE + IMM2_SIZE; break; + case OP_BRAZERO: + case OP_BRAMINZERO: + case OP_BRAPOSZERO: + repeat_check = FALSE; + size = 1; + break; + CASE_ITERATOR_PRIVATE_DATA_1 space = 1; size = -2; diff --git a/testdata/testinput2 b/testdata/testinput2 index 282cd0d..36e918e 100644 --- a/testdata/testinput2 +++ b/testdata/testinput2 @@ -4403,4 +4403,6 @@ a random value. /Ix /(*CRLF)(*LIMIT_MATCH=)abc/ +/(?:ab)?(?:ab)(?:ab)/ + # End of testinput2 diff --git a/testdata/testoutput2 b/testdata/testoutput2 index 0c5f44b..d8d399a 100644 --- a/testdata/testoutput2 +++ b/testdata/testoutput2 @@ -14657,4 +14657,6 @@ Failed: error 160 at offset 14: (*VERB) not recognized or malformed /(*CRLF)(*LIMIT_MATCH=)abc/ Failed: error 160 at offset 21: (*VERB) not recognized or malformed +/(?:ab)?(?:ab)(?:ab)/ + # End of testinput2