After failed to match in matching mode, dfa transits initial state
when not allow newline or next state when allow new line instead of
return NULL.

That will cause next matching at position or infinit loop.  By the
way, theere is no affair for grep in order that it always uses not
matching mode but searching mode.

First patch fixes the bug, and second patch simplifies around the code.
From 54910755c76a6a04411afa613645cfb203ce1be0 Mon Sep 17 00:00:00 2001
From: Norihiro Tanaka <[email protected]>
Date: Tue, 2 Dec 2014 22:45:17 +0900
Subject: [PATCH 1/2] dfa: matching at next position or infinit loop in
 matching mode

After failed to match in matching mode, dfa transits initial state
when not allow newline or next state when allow new line instead of
return NULL.  That will cause next matching at position or infinit
loop.  By the way, theere is no affair for grep in order that it
always uses not matching mode but searching mode.

* src/dfa.c (dfaexec_main): After failed to match in matching mode
return NULL instead of transition to next state.
---
 src/dfa.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/src/dfa.c b/src/dfa.c
index 65862e8..4ab2b72 100644
--- a/src/dfa.c
+++ b/src/dfa.c
@@ -3498,13 +3498,16 @@ dfaexec_main (struct dfa *d, char const *begin, char 
*end,
           continue;
         }
 
-      if (p[-1] == eol && allow_nl)
+      if (p[-1] != eol || d->newlines[s1] < 0)
         {
-          s = d->newlines[s1];
-          continue;
+          p = NULL;
+          goto done;
         }
 
-      s = 0;
+      if (allow_nl)
+        s = d->newlines[s1];
+      else
+        s = 0;
     }
 
  done:
-- 
2.2.0

From e1b5054593863dfdd913b9b843045d47b4585b04 Mon Sep 17 00:00:00 2001
From: Norihiro Tanaka <[email protected]>
Date: Tue, 2 Dec 2014 22:58:37 +0900
Subject: [PATCH 2/2] dfa: implification of dfaexec

* src/dfa.c (dfaexec): Simplify by rearrangement of IF conditions.  This
change does not change any logics, but minor speed-up or slowdown may be
caused due to optimization by a compiler.  This change is partial revert
for a change in bafa1341db643225c2421ecca90353e556dedae5.
---
 src/dfa.c | 46 ++++++++++++++++++----------------------------
 1 file changed, 18 insertions(+), 28 deletions(-)

diff --git a/src/dfa.c b/src/dfa.c
index 4ab2b72..41b1031 100644
--- a/src/dfa.c
+++ b/src/dfa.c
@@ -3459,13 +3459,25 @@ dfaexec_main (struct dfa *d, char const *begin, char 
*end,
             }
         }
 
-      if ((char *) p > end)
+      if (s < 0)
         {
-          p = NULL;
-          goto done;
-        }
+          if ((char *) p > end || p[-1] != eol || d->newlines[s1] < 0)
+            {
+              p = NULL;
+              goto done;
+            }
 
-      if (s >= 0 && d->fails[s])
+          /* If the previous character was a newline, count it, and skip
+             checking of multibyte character boundary until here.  */
+          nlcount++;
+          mbp = p;
+
+          if (allow_nl)
+            s = d->newlines[s1];
+          else
+            s = 0;
+        }
+      if (d->fails[s])
         {
           if (d->success[s] & sbit[*p])
             {
@@ -3479,35 +3491,13 @@ dfaexec_main (struct dfa *d, char const *begin, char 
*end,
             State_transition();
           else
             s = d->fails[s][*p++];
-          continue;
         }
-
-      /* If the previous character was a newline, count it, and skip
-         checking of multibyte character boundary until here.  */
-      if (p[-1] == eol)
-        {
-          nlcount++;
-          mbp = p;
-        }
-
-      if (s >= 0)
+      else
         {
           if (!d->trans[s])
             build_state (s, d);
           trans = d->trans;
-          continue;
         }
-
-      if (p[-1] != eol || d->newlines[s1] < 0)
-        {
-          p = NULL;
-          goto done;
-        }
-
-      if (allow_nl)
-        s = d->newlines[s1];
-      else
-        s = 0;
     }
 
  done:
-- 
2.2.0

Reply via email to