From 1c09efe6b0008a3b463299efe7501bc3140806f3 Mon Sep 17 00:00:00 2001
From: Zoltan Herczeg <hzmester@freemail.hu>
Date: Wed, 6 Dec 2023 10:06:50 +0000
Subject: [PATCH] Fix accept and endanchored interaction in JIT

---
 src/pcre2_jit_compile.c | 15 ++++++++++++---
 src/pcre2_jit_test.c    |  1 +
 2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/src/pcre2_jit_compile.c b/src/pcre2_jit_compile.c
index 2e11c3c..849e2c8 100644
--- a/src/pcre2_jit_compile.c
+++ b/src/pcre2_jit_compile.c
@@ -489,6 +489,8 @@ typedef struct compiler_common {
   jump_list *casefulcmp;
   jump_list *caselesscmp;
   jump_list *reset_match;
+  /* Same as reset_match, but resets the STR_PTR as well. */
+  jump_list *restart_match;
   BOOL unset_backref;
   BOOL alt_circumflex;
 #ifdef SUPPORT_UNICODE
@@ -3146,7 +3148,7 @@ return (value & (value - 1)) == 0;
 
 static SLJIT_INLINE void set_jumps(jump_list *list, struct sljit_label *label)
 {
-while (list)
+while (list != NULL)
   {
   /* sljit_set_label is clever enough to do nothing
   if either the jump or the label is NULL. */
@@ -12187,7 +12189,7 @@ if (*cc == OP_FAIL)
   }
 
 if (*cc == OP_ACCEPT && common->currententry == NULL && (common->re->overall_options & PCRE2_ENDANCHORED) != 0)
-  add_jump(compiler, &common->reset_match, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, STR_END, 0));
+  add_jump(compiler, &common->restart_match, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, STR_END, 0));
 
 if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL || !common->might_be_empty)
   {
@@ -14552,10 +14554,17 @@ if (common->caselesscmp != NULL)
   set_jumps(common->caselesscmp, LABEL());
   do_caselesscmp(common);
   }
-if (common->reset_match != NULL)
+if (common->reset_match != NULL || common->restart_match != NULL)
   {
+  if (common->restart_match != NULL)
+    {
+    set_jumps(common->restart_match, LABEL());
+    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr);
+    }
+
   set_jumps(common->reset_match, LABEL());
   do_reset_match(common, (re->top_bracket + 1) * 2);
+  /* The value of restart_match is in TMP1. */
   CMPTO(SLJIT_GREATER, STR_PTR, 0, TMP1, 0, continue_match_label);
   OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
   JUMPTO(SLJIT_JUMP, reset_match_label);
diff --git a/src/pcre2_jit_test.c b/src/pcre2_jit_test.c
index b5d95d5..0974d19 100644
--- a/src/pcre2_jit_test.c
+++ b/src/pcre2_jit_test.c
@@ -655,6 +655,7 @@ static struct regression_test_case regression_test_cases[] = {
 	{ MU, A, 0, 0, "(?=(a(b(*ACCEPT)b)))a", "ab" },
 	{ MU, A, PCRE2_NOTEMPTY, 0, "(?=a*(*ACCEPT))c", "c" },
 	{ MU, A, PCRE2_NOTEMPTY, 0 | F_NOMATCH, "(?=A)", "AB" },
+	{ MU | PCRE2_ENDANCHORED, A, 0, 0, "aa(*ACCEPT)aa", "aaa" },
 
 	/* Conditional blocks. */
 	{ MU, A, 0, 0, "(?(?=(a))a|b)+k", "ababbalbbadabak" },
-- 
2.33.0

