diff --git a/ChangeLog b/ChangeLog index 2edaed6..a7d18a1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14,6 +14,9 @@ error. This bug was discovered by the LLVM fuzzer. 4. Implemented pcre2_callout_enumerate(). +5. Fix JIT compilation of conditional blocks whose assertion + is converted to (*FAIL). E.g: /(?(?!))/. + Version 10.10 06-March-2015 --------------------------- diff --git a/src/pcre2_jit_compile.c b/src/pcre2_jit_compile.c index 8578891..f23c136 100644 --- a/src/pcre2_jit_compile.c +++ b/src/pcre2_jit_compile.c @@ -7044,7 +7044,7 @@ if (SLJIT_UNLIKELY(opcode == OP_COND || opcode == OP_SCOND)) { SLJIT_COMPILE_ASSERT(OP_DNRREF == OP_RREF + 1 && OP_FALSE == OP_RREF + 2 && OP_TRUE == OP_RREF + 3, compile_time_checks_must_be_grouped_together); - has_alternatives = (*matchingpath >= OP_RREF && *matchingpath <= OP_TRUE) ? FALSE : TRUE; + has_alternatives = ((*matchingpath >= OP_RREF && *matchingpath <= OP_TRUE) || *matchingpath == OP_FAIL) ? FALSE : TRUE; } if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN)) @@ -7303,7 +7303,7 @@ if (opcode == OP_COND || opcode == OP_SCOND) add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), JUMP(SLJIT_ZERO)); matchingpath += 1 + 2 * IMM2_SIZE; } - else if (*matchingpath >= OP_RREF && *matchingpath <= OP_TRUE) + else if ((*matchingpath >= OP_RREF && *matchingpath <= OP_TRUE) || *matchingpath == OP_FAIL) { /* Never has other case. */ BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL; @@ -7314,7 +7314,7 @@ if (opcode == OP_COND || opcode == OP_SCOND) stacksize = 1; matchingpath++; } - else if (*matchingpath == OP_FALSE) + else if (*matchingpath == OP_FALSE || *matchingpath == OP_FAIL) stacksize = 0; else if (*matchingpath == OP_RREF) { diff --git a/src/pcre2_jit_test.c b/src/pcre2_jit_test.c index ad74013..b076c67 100644 --- a/src/pcre2_jit_test.c +++ b/src/pcre2_jit_test.c @@ -647,6 +647,9 @@ static struct regression_test_case regression_test_cases[] = { { MU, A, 0, 0, "(?Pa)?(?Pb)?(?(Name)c|d)+?dd", "bcabcacdb bdddd" }, { MU, A, 0, 0, "(?Pa)?(?Pb)?(?(Name)c|d)+l", "ababccddabdbccd abcccl" }, { MU, A, 0, 0, "((?:a|aa)(?(1)aaa))x", "aax" }, + { MU, A, 0, 0, "(?(?!)a|b)", "ab" }, + { MU, A, 0, 0, "(?(?!)a)", "ab" }, + { MU, A, 0, 0 | F_NOMATCH, "(?(?!)a|b)", "ac" }, /* Set start of match. */ { MU, A, 0, 0, "(?:\\Ka)*aaaab", "aaaaaaaa aaaaaaabb" },