From c0d0f2f65ef0a3c99132e5cebf3a985919b65e20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Herczeg?= Date: Mon, 16 Nov 2015 08:30:48 +0000 Subject: [PATCH] Fix two offset_limit bug in JIT. --- ChangeLog | 2 ++ src/pcre2_jit_compile.c | 42 ++++++++++++++++++++++++++--------------- testdata/testinput2 | 4 ++++ testdata/testoutput2 | 6 ++++++ 4 files changed, 39 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1ba8df1..2472fa0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -312,6 +312,8 @@ about JIT compile failures in pcre2test. 93. Re-arrange valgrind support code in pcre2test to avoid spurious reports with JIT (possibly caused by SSE2?). +94. Support offset_limit in JIT. + Version 10.20 30-June-2015 -------------------------- diff --git a/src/pcre2_jit_compile.c b/src/pcre2_jit_compile.c index 671ed15..2ca5a26 100644 --- a/src/pcre2_jit_compile.c +++ b/src/pcre2_jit_compile.c @@ -3318,6 +3318,8 @@ if (!(hascrorlf || (overall_options & PCRE2_FIRSTLINE) != 0) && (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF || common->newline > 255)) newlinecheck = TRUE; +SLJIT_ASSERT(common->forced_quit_label == NULL); + if ((overall_options & PCRE2_FIRSTLINE) != 0) { /* Search for the end of the first line. */ @@ -3357,23 +3359,25 @@ else if ((overall_options & PCRE2_USE_OFFSET_LIMIT) != 0) /* Check whether offset limit is set and valid. */ SLJIT_ASSERT(common->match_end_ptr != 0); - OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, offset_limit)); - OP1(SLJIT_MOV, TMP1, 0, STR_END, 0); - end = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, (sljit_sw) PCRE2_UNSET); -#if PCRE2_CODE_UNIT_WIDTH == 16 - OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); -#elif PCRE2_CODE_UNIT_WIDTH == 32 - OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 2); -#endif OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); - OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0); - end2 = CMP(SLJIT_LESS_EQUAL, TMP1, 0, STR_END, 0); - OP1(SLJIT_MOV, TMP1, 0, STR_END, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, offset_limit)); + OP1(SLJIT_MOV, TMP2, 0, STR_END, 0); + end = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, (sljit_sw) PCRE2_UNSET); + OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); +#if PCRE2_CODE_UNIT_WIDTH == 16 + OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); +#elif PCRE2_CODE_UNIT_WIDTH == 32 + OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 2); +#endif + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); + OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0); + end2 = CMP(SLJIT_LESS_EQUAL, TMP2, 0, STR_END, 0); + OP1(SLJIT_MOV, TMP2, 0, STR_END, 0); JUMPHERE(end2); + OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH); + add_jump(compiler, &common->forced_quit, CMP(SLJIT_LESS, TMP2, 0, STR_PTR, 0)); JUMPHERE(end); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, TMP1, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, TMP2, 0); } start = JUMP(SLJIT_JUMP); @@ -11200,7 +11204,15 @@ if ((re->overall_options & PCRE2_ANCHORED) == 0) /* There cannot be more newlines if PCRE2_FIRSTLINE is set. */ if ((re->overall_options & PCRE2_FIRSTLINE) == 0) { - CMPTO(SLJIT_LESS, STR_PTR, 0, (common->match_end_ptr == 0) ? STR_END : TMP1, 0, common->ff_newline_shortcut); + if (common->match_end_ptr != 0) + { + OP1(SLJIT_MOV, TMP3, 0, STR_END, 0); + OP1(SLJIT_MOV, STR_END, 0, TMP1, 0); + CMPTO(SLJIT_LESS, STR_PTR, 0, TMP1, 0, common->ff_newline_shortcut); + OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); + } + else + CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, common->ff_newline_shortcut); } } else diff --git a/testdata/testinput2 b/testdata/testinput2 index 796b59d..a6cfd85 100644 --- a/testdata/testinput2 +++ b/testdata/testinput2 @@ -4534,6 +4534,10 @@ B)x/alt_verbnames,mark \= Expect error 1234abcde\=offset_limit=4 +/^\w/m,use_offset_limit + \n..\naa\=offset_limit=3 + \n..\naa\=offset_limit=4 + /abcd/null_context abcd\=null_context \= Expect error diff --git a/testdata/testoutput2 b/testdata/testoutput2 index fd56e34..9408756 100644 --- a/testdata/testoutput2 +++ b/testdata/testoutput2 @@ -14604,6 +14604,12 @@ No match 1234abcde\=offset_limit=4 Failed: error -56: offset limit set without PCRE2_USE_OFFSET_LIMIT +/^\w/m,use_offset_limit + \n..\naa\=offset_limit=3 +No match + \n..\naa\=offset_limit=4 + 0: a + /abcd/null_context abcd\=null_context 0: abcd