From 3ec328fe1b8d45197cb09a62a54a908778c1ae7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Herczeg?= Date: Tue, 11 Aug 2015 05:30:10 +0000 Subject: [PATCH] The JIT compiler should not check repeats after a {0,1} repeat byte code. --- ChangeLog | 3 +++ src/pcre2_jit_compile.c | 13 ++++++++++++- testdata/testinput2 | 2 ++ testdata/testoutput2 | 2 ++ 4 files changed, 19 insertions(+), 1 deletion(-) 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