The JIT compiler should restore the control chain for empty possessive repeats.

This commit is contained in:
Zoltán Herczeg 2015-08-11 13:20:37 +00:00
parent 3ec328fe1b
commit d210396121
4 changed files with 27 additions and 3 deletions

View File

@ -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. 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. 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 Version 10.20 30-June-2015
-------------------------- --------------------------

View File

@ -8055,6 +8055,10 @@ while (*cc != OP_KETRPOS)
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 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) if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
add_jump(compiler, &emptymatch, CMP(SLJIT_EQUAL, TMP1, 0, STR_PTR, 0)); 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); 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) if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
add_jump(compiler, &emptymatch, CMP(SLJIT_EQUAL, TMP1, 0, STR_PTR, 0)); 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); JUMPTO(SLJIT_JUMP, loop);
flush_stubs(common); flush_stubs(common);

6
testdata/testinput2 vendored
View File

@ -4404,5 +4404,11 @@ a random value. /Ix
/(*CRLF)(*LIMIT_MATCH=)abc/ /(*CRLF)(*LIMIT_MATCH=)abc/
/(?:ab)?(?:ab)(?:ab)/ /(?:ab)?(?:ab)(?:ab)/
abab
ababab
aba
/((*MARK:A))++a(*SKIP:B)b/
aacb
# End of testinput2 # End of testinput2

10
testdata/testoutput2 vendored
View File

@ -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 Failed: error 160 at offset 21: (*VERB) not recognized or malformed
/(?:ab)?(?:ab)(?:ab)/ /(?:ab)?(?:ab)(?:ab)/
abab
0: abab
ababab
0: ababab
aba
No match
/((*MARK:A))++a(*SKIP:B)b/
aacb
No match
# End of testinput2 # End of testinput2