From 674b6640e702705e8e90125f972197fae3aa364d Mon Sep 17 00:00:00 2001
From: Philip Hazel <Philip.Hazel@gmail.com>
Date: Sat, 3 Aug 2024 17:18:56 +0100
Subject: [PATCH] Remove incorrect optimization in DFA matching when partial
 matching and (*F) are involved
 
Conflict:don't modify ChangeLog; adapt context
Reference:https://github.com/PCRE2Project/pcre2/commit/674b6640e702705e8e90125f972197fae3aa364d

---
 src/pcre2_dfa_match.c | 10 +---------
 testdata/testinput6   |  9 +++++++++
 testdata/testoutput6  | 13 +++++++++++++
 3 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/src/pcre2_dfa_match.c b/src/pcre2_dfa_match.c
index 84b0a6a..7af9d91 100644
--- a/src/pcre2_dfa_match.c
+++ b/src/pcre2_dfa_match.c
@@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language.
 
                        Written by Philip Hazel
      Original API code Copyright (c) 1997-2012 University of Cambridge
-          New API code Copyright (c) 2016-2021 University of Cambridge
+          New API code Copyright (c) 2016-2024 University of Cambridge
 
 -----------------------------------------------------------------------------
 Redistribution and use in source and binary forms, with or without
@@ -693,7 +693,6 @@ for (;;)
   int i, j;
   int clen, dlen;
   uint32_t c, d;
-  int forced_fail = 0;
   BOOL partial_newline = FALSE;
   BOOL could_continue = reset_could_continue;
   reset_could_continue = FALSE;
@@ -2708,7 +2707,6 @@ for (;;)
       though the other "backtracking verbs" are not supported. */
 
       case OP_FAIL:
-      forced_fail++;    /* Count FAILs for multiple states */
       break;
 
       case OP_ASSERT:
@@ -3190,18 +3188,12 @@ for (;;)
   matches that we are going to find. If partial matching has been requested,
   check for appropriate conditions.
 
-  The "forced_ fail" variable counts the number of (*F) encountered for the
-  character. If it is equal to the original active_count (saved in
-  workspace[1]) it means that (*F) was found on every active state. In this
-  case we don't want to give a partial match.
-
   The "could_continue" variable is true if a state could have continued but
   for the fact that the end of the subject was reached. */
 
   if (new_count <= 0)
     {
     if (could_continue &&                            /* Some could go on, and */
-        forced_fail != workspace[1] &&               /* Not all forced fail & */
         (                                            /* either... */
         (mb->moptions & PCRE2_PARTIAL_HARD) != 0      /* Hard partial */
         ||                                           /* or... */
diff --git a/testdata/testinput6 b/testdata/testinput6
index 0ca0d23..b71a69c 100644
--- a/testdata/testinput6
+++ b/testdata/testinput6
@@ -4392,9 +4392,18 @@
 
 /Z(*F)Q|ZXY/
     Z\=ps
+    XY\=dfa_restart 
 \= Expect no match 
     ZA\=ps
     X\=ps
+    
+/Z(?:(*F)Q|XY)/
+    Z\=ps
+    XY\=dfa_restart 
+    
+/Z(*F)Q|Z(*F)XY/
+\= Expect no match
+    Z\=ps
 
 /\bthe cat\b/
     the cat\=ps
diff --git a/testdata/testoutput6 b/testdata/testoutput6
index 607b572..38c653e 100644
--- a/testdata/testoutput6
+++ b/testdata/testoutput6
@@ -6769,11 +6769,24 @@ Partial match: dogs
 /Z(*F)Q|ZXY/
     Z\=ps
 Partial match: Z
+    XY\=dfa_restart 
+ 0: XY
 \= Expect no match 
     ZA\=ps
 No match
     X\=ps
 No match
+    
+/Z(?:(*F)Q|XY)/
+    Z\=ps
+Partial match: Z
+    XY\=dfa_restart 
+ 0: XY
+    
+/Z(*F)Q|Z(*F)XY/
+\= Expect no match
+    Z\=ps
+No match
 
 /\bthe cat\b/
     the cat\=ps
-- 
2.43.0

