Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions src/pcre2_compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -10254,6 +10254,7 @@ get_branchlength(uint32_t **pptrptr, int *minptr, int *errcodeptr, int *lcptr,
uint32_t group = 0;
uint32_t itemlength = 0;
uint32_t itemminlength = 0;
BOOL cond_no_else = FALSE;

if (*pptr < META_END)
{
Expand Down Expand Up @@ -10542,14 +10543,20 @@ get_branchlength(uint32_t **pptrptr, int *minptr, int *errcodeptr, int *lcptr,
case META_COND_RNAME:
case META_COND_RNUMBER:
pptr += 2 + SIZEOFFSET;
goto CHECK_GROUP;
goto CHECK_COND;

case META_COND_ASSERT:
pptr += 1;
goto CHECK_GROUP;
goto CHECK_COND;

case META_COND_VERSION:
pptr += 4;

CHECK_COND:
gptr = parsed_skip(pptr, PSKIP_ALT);
if (gptr == NULL)
return -1;
cond_no_else = *gptr == META_KET;
goto CHECK_GROUP;

case META_CAPTURE:
Expand All @@ -10566,7 +10573,7 @@ get_branchlength(uint32_t **pptrptr, int *minptr, int *errcodeptr, int *lcptr,
if (grouplength < 0)
return -1;
itemlength = grouplength;
itemminlength = groupminlength;
itemminlength = cond_no_else ? 0 : groupminlength;
break;

case META_QUERY:
Expand Down
6 changes: 1 addition & 5 deletions src/pcre2_jit_char_inc.h
Original file line number Diff line number Diff line change
Expand Up @@ -2036,12 +2036,8 @@ compile_char1_matchingpath(compiler_common *common, PCRE2_UCHAR type, PCRE2_SPTR
detect_partial_match(common, backtracks);
read_char(common, common->bsr_nlmin, common->bsr_nlmax, NULL, 0);
jump[0] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
/* We don't need to handle soft partial matching case. */
end_list = NULL;
if (common->mode != PCRE2_JIT_PARTIAL_HARD)
add_jump(compiler, &end_list, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
else
check_str_end(common, &end_list);
check_str_end(common, &end_list);
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, CHAR_NL);
OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_EQUAL);
Expand Down
59 changes: 40 additions & 19 deletions src/pcre2_jit_compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -4215,17 +4215,20 @@ check_str_end(compiler_common *common, jump_list **end_reached)
}

jump = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);
if (common->mode == PCRE2_JIT_PARTIAL_SOFT)
{
if (!common->allow_empty_partial)
add_jump(compiler, end_reached,
CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0));
else if (common->mode == PCRE2_JIT_PARTIAL_SOFT)
add_jump(compiler, end_reached,
CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, -1));

if (common->mode == PCRE2_JIT_PARTIAL_SOFT)
{
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0);
add_jump(compiler, end_reached, JUMP(SLJIT_JUMP));
}
else
{
add_jump(compiler, end_reached,
CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0));
if (common->partialmatchlabel != NULL)
JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
else
Expand Down Expand Up @@ -5875,7 +5878,7 @@ do_getucdtype(compiler_common *common)
#endif /* SUPPORT_UNICODE */

static SLJIT_INLINE struct sljit_label *
mainloop_entry(compiler_common *common)
mainloop_entry(compiler_common *common, jump_list **limit_reached)
{
DEFINE_COMPILER;
struct sljit_label *mainloop;
Expand Down Expand Up @@ -6061,6 +6064,11 @@ mainloop_entry(compiler_common *common)
JUMPHERE(end2);
}

if ((readuchar || newlinecheck) &&
(overall_options & (PCRE2_FIRSTLINE | PCRE2_USE_OFFSET_LIMIT)) == PCRE2_USE_OFFSET_LIMIT)
add_jump(compiler, limit_reached,
CMP(SLJIT_GREATER, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr));

return mainloop;
}

Expand Down Expand Up @@ -6181,6 +6189,7 @@ scan_prefix(compiler_common *common, PCRE2_SPTR cc, fast_forward_char_data *char
--stack_ptr;
cc = cc_stack[stack_ptr];
chars = chars_stack[stack_ptr];
repeat = 1;

if (chars >= chars_end)
continue;
Expand Down Expand Up @@ -9761,10 +9770,7 @@ compile_assert_matchingpath(compiler_common *common, PCRE2_SPTR cc, assert_backt
}

if (end_block_size > 0)
{
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_END, 0);
OP1(SLJIT_MOV, STR_END, 0, STR_PTR, 0);
}

memset(&altbacktrack, 0, sizeof(backtrack_common));
if (conditional || (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT))
Expand All @@ -9777,7 +9783,8 @@ compile_assert_matchingpath(compiler_common *common, PCRE2_SPTR cc, assert_backt
common->quit = NULL;
}

common->in_positive_assertion = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK);
common->in_positive_assertion =
(opcode == OP_ASSERT || opcode == OP_ASSERTBACK) && !local_quit_available;
common->positive_assertion_quit = NULL;

while (1)
Expand Down Expand Up @@ -9818,9 +9825,17 @@ compile_assert_matchingpath(compiler_common *common, PCRE2_SPTR cc, assert_backt

if (has_vreverse)
{
SLJIT_ASSERT(altbacktrack.top != NULL);
add_jump(compiler, &altbacktrack.top->simple_backtracks,
CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0));
SLJIT_ASSERT(altbacktrack.top != NULL && extrasize > 0);
if (framesize == no_stack)
add_jump(compiler, &altbacktrack.top->simple_backtracks,
CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)));
else
{
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
add_jump(compiler, &altbacktrack.top->simple_backtracks,
CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1),
STACK(-(framesize < 0 ? 0 : framesize) - extrasize)));
}
}

common->accept_label = LABEL();
Expand Down Expand Up @@ -10632,7 +10647,6 @@ compile_bracket_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_c
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw), STR_END, 0);
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
OP1(SLJIT_MOV, STR_END, 0, STR_PTR, 0);

has_vreverse = (*matchingpath == OP_VREVERSE);
if (*matchingpath == OP_REVERSE || has_vreverse)
Expand Down Expand Up @@ -10874,7 +10888,7 @@ compile_bracket_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_c
{
SLJIT_ASSERT(backtrack->top != NULL && PRIVATE_DATA(ccbegin + 1));
add_jump(compiler, &backtrack->top->simple_backtracks,
CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0));
CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr));
}

if (PRIVATE_DATA(ccbegin + 1))
Expand Down Expand Up @@ -13344,8 +13358,6 @@ compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_commo
if (common->restore_end_ptr == 0)
common->restore_end_ptr = private_data_ptr + sizeof(sljit_sw);
}
else if (SLJIT_UNLIKELY(opcode == OP_ASSERTBACK_NA) && PRIVATE_DATA(ccbegin + 1))
OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);

if (SLJIT_UNLIKELY(opcode == OP_ONCE))
{
Expand Down Expand Up @@ -13485,7 +13497,7 @@ compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_commo
{
SLJIT_ASSERT(current->top != NULL && PRIVATE_DATA(ccbegin + 1));
add_jump(compiler, &current->top->simple_backtracks,
CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0));
CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr));
}

if (PRIVATE_DATA(ccbegin + 1))
Expand Down Expand Up @@ -13858,7 +13870,7 @@ compile_control_verb_backtrackingpath(compiler_common *common, struct backtrack_
add_jump(compiler, &common->then_trap->quit, JUMP(SLJIT_JUMP));
return;
}
else if (!common->local_quit_available && common->in_positive_assertion)
else if (common->in_positive_assertion)
{
add_jump(compiler, &common->positive_assertion_quit, JUMP(SLJIT_JUMP));
return;
Expand Down Expand Up @@ -13962,6 +13974,12 @@ compile_then_trap_backtrackingpath(compiler_common *common, struct backtrack_com
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
free_stack(common, 3);

if (current->prev != NULL && *current->prev->cc == OP_VREVERSE)
{
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, TMP1, 0);
add_jump(compiler, &current->prev->own_backtracks, JUMP(SLJIT_JUMP));
}

JUMPHERE(jump);
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, TMP1, 0);
}
Expand Down Expand Up @@ -14424,6 +14442,7 @@ jit_compile(pcre2_code *code, sljit_u32 mode)
struct sljit_jump *empty_match = NULL;
struct sljit_jump *end_anchor_failed = NULL;
jump_list *reqcu_not_found = NULL;
jump_list *limit_reached = NULL;

SLJIT_ASSERT(tables);

Expand Down Expand Up @@ -14719,7 +14738,7 @@ jit_compile(pcre2_code *code, sljit_u32 mode)
/* Main part of the matching */
if ((re->overall_options & PCRE2_ANCHORED) == 0)
{
mainloop_label = mainloop_entry(common);
mainloop_label = mainloop_entry(common, &limit_reached);
continue_match_label = LABEL();
/* Forward search if possible. */
if ((re->optimization_flags & PCRE2_OPTIM_START_OPTIMIZE) != 0)
Expand Down Expand Up @@ -14922,6 +14941,8 @@ jit_compile(pcre2_code *code, sljit_u32 mode)
/* No more remaining characters. */
if (reqcu_not_found != NULL)
set_jumps(reqcu_not_found, LABEL());
if (limit_reached != NULL)
set_jumps(limit_reached, LABEL());

if (mode == PCRE2_JIT_PARTIAL_SOFT)
CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, -1,
Expand Down
33 changes: 33 additions & 0 deletions src/pcre2_jit_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,19 @@ static struct regression_test_case regression_test_cases[] = {
{ MU, A, 0, 0, "(?(?<!|(|a)))", "a" },
{ MU, A, 0, 0, "(?=((?|(a)(.)|(b)(..)|(c)(...)))(?1(2,3))).x", "b12c123bx2c123" },
{ MU, A, 0, 3, "(?<*(.).{,2})\\1", "BABA" },
{ MU, A, 0, 0, "y(?<!.{1,2}\\b)b", "eyb" },
{ M, A, 0, 0, "y(?<!.{1,2}\\b)b", "e yb" },
{ MU, A, 0, 0 | F_NOMATCH, "(?<=.{1,2}\\b)yb", "eyb" },
{ M, A, 0, 0, "(?<=.{1,2}\\b)yb", "e yb" },
{ MU, A, 0, 0 | F_NOMATCH, "(?<=ab[kK]{2,3}|[ab]key.{2}|ee\\b)k", "eek" },
{ MU, A, 0, 0, "(?<=a.{1,2}\\B)c", "abc" },
{ MU, A, 0, 0, "(?<=x.{1,2}(?=z))z", "xyyz" },
{ MU, A, 0, 0, "(?<=a.{0,3}$)", "abc" },
{ MU, A, 0, 0, "(?<=a.{0,2})c", "acc" },
{ MU, A, 0, 0, "(?(?<=a.{1,2}\\b)c|d)", "ab c" },
{ MU, A, 0, 0, "(?<*x.{1,2}\\b|zz.{1,3}\\b)c", "zzab c" },
{ MU, A, 0, 0 | F_NOMATCH, "(?<*x.{1,2}\\b|zz.{1,3}\\b)c", "zzabc" },
{ MU, A, 0, 0, "(?<*a.{1,2}\\b)(?<=a.{1,2})c", "ab c" },

/* Not empty, ACCEPT, FAIL */
{ MU, A, PCRE2_NOTEMPTY, 0 | F_NOMATCH, "a*", "bcx" },
Expand Down Expand Up @@ -833,6 +846,15 @@ static struct regression_test_case regression_test_cases[] = {
{ MU, A, PCRE2_PARTIAL_HARD, 0, "a\\b", "a" },
{ M | PCRE2_DUPNAMES, A, PCRE2_PARTIAL_HARD, 0, "^(?P<NAME>..)(?P<NAME>..)\\k<NAME>{2,4}", "AaAAAaAaAaA" },
{ M | PCRE2_DUPNAMES, A, PCRE2_PARTIAL_HARD, 0, "^(?P<NAME>..)(?P<NAME>..)\\k<NAME>{2,4}", "AaAAAaAaAaa" },
{ MU, A, PCRE2_PARTIAL_SOFT, 0, "\\R(*F)", "\r" },
{ MU, A, PCRE2_PARTIAL_SOFT, 0, "(?:\\R|z)(*F)", "\r" },
{ MU, A, PCRE2_PARTIAL_SOFT, 0, "(?=(?!\\R)?})", "\r" },
{ MU, A, PCRE2_PARTIAL_SOFT, 0 | F_NOMATCH, "(?<!(x))\\1", "ab" },
{ MU, A, PCRE2_PARTIAL_HARD, 0, "x\\R?", "x\r" },
{ MU, A, PCRE2_PARTIAL_SOFT, 0, "\\R?(*F)", "\r" },
{ MU, A, PCRE2_PARTIAL_HARD, 0, "\\b", "" },
{ MU, A, PCRE2_PARTIAL_HARD, 0, "((?<=\\b!?))", "" },
{ MU, A, PCRE2_PARTIAL_HARD, 0, "^\\bw", "" },

/* (*MARK) verb. */
{ MU, A, 0, 0, "a(*MARK:aa)a", "ababaa" },
Expand Down Expand Up @@ -910,6 +932,17 @@ static struct regression_test_case regression_test_cases[] = {
{ MU, A, 0, 0, "(?=(*THEN: ))* ", " " },
{ MU, A, 0, 0, "a(*THEN)(?R) |", "a" },
{ MU, A, 0, 0 | F_NOMATCH, "(?<!(*THEN)a|(*THEN)b|(*THEN)ab?|(*THEN)ba?|)", "c" },
{ MU, A, 0, 0 | F_NOMATCH, "(?<=a?(*THEN)(?<=e)|x)B", "eBx" },
{ MU, A, 0, 0 | F_NOMATCH, "(?<=x|a?(*THEN)(?<=e))B", "eBx" },
{ MU, A, 0, 0 | F_NOMATCH, "((?<*(a)?(*THEN)))[a-c]", "eb" },
{ MU, A, 0, 0 | F_NOMATCH, "(?!(?=(*THEN)(*F))?)", "x" },
{ MU, A, 0, 0 | F_NOMATCH, "(?!(?<=a?(*THEN))?)b", "xb" },
{ MU, A, 0, 2, "(*naplb:(?(?=x)a))", "ae" },
{ MU, A, 0, 2, "(?<=(?(?=e)a))", "ae" },
{ MU, A, 0, 3, "(*naplb:(?(?=x)ab))", "xabe" },
{ MU, A, 0, 0, "(?:xyzw\\R{4}|abc)", "abc" },
{ M, A, 0, 0, "(?:xyzw\\X{3}|abc)", "abc" },
{ M, A, 0, 0, "(?:wxyz\\h{2}|abcd)", "abcd" },

/* Recurse and control verbs. */
{ MU, A, 0, 0, "(a(*ACCEPT)b){0}a(?1)b", "aacaabb" },
Expand Down
Loading
Loading