diff --git a/ChangeLog b/ChangeLog index 8bf26c4..03c4e89 100644 --- a/ChangeLog +++ b/ChangeLog @@ -136,6 +136,9 @@ 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. +37. The JIT compiler should restore the control chain for empty possessive +repeats. 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 d72112b..0519918 100644 --- a/src/pcre2_jit_compile.c +++ b/src/pcre2_jit_compile.c @@ -8055,6 +8055,10 @@ while (*cc != OP_KETRPOS) OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); } + /* Even if the match is empty, we need to reset the control head. */ + if (needs_control_head) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack)); + if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS) add_jump(compiler, &emptymatch, CMP(SLJIT_EQUAL, TMP1, 0, STR_PTR, 0)); @@ -8082,6 +8086,10 @@ while (*cc != OP_KETRPOS) OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_sw), STR_PTR, 0); } + /* Even if the match is empty, we need to reset the control head. */ + if (needs_control_head) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack)); + if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS) add_jump(compiler, &emptymatch, CMP(SLJIT_EQUAL, TMP1, 0, STR_PTR, 0)); @@ -8094,9 +8102,6 @@ while (*cc != OP_KETRPOS) } } - if (needs_control_head) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack)); - JUMPTO(SLJIT_JUMP, loop); flush_stubs(common); diff --git a/testdata/testinput2 b/testdata/testinput2 index 36e918e..a4131d5 100644 --- a/testdata/testinput2 +++ b/testdata/testinput2 @@ -4404,5 +4404,11 @@ a random value. /Ix /(*CRLF)(*LIMIT_MATCH=)abc/ /(?:ab)?(?:ab)(?:ab)/ + abab + ababab + aba + +/((*MARK:A))++a(*SKIP:B)b/ + aacb # End of testinput2 diff --git a/testdata/testoutput2 b/testdata/testoutput2 index d8d399a..36612b9 100644 --- a/testdata/testoutput2 +++ b/testdata/testoutput2 @@ -14658,5 +14658,15 @@ Failed: error 160 at offset 14: (*VERB) not recognized or malformed Failed: error 160 at offset 21: (*VERB) not recognized or malformed /(?:ab)?(?:ab)(?:ab)/ + abab + 0: abab + ababab + 0: ababab + aba +No match + +/((*MARK:A))++a(*SKIP:B)b/ + aacb +No match # End of testinput2