]> Savannah Git Hosting - gnulib.git/commitdiff
dfa: avoid new infinite loop
authorJim Meyering <meyering@fb.com>
Tue, 29 Nov 2016 18:45:46 +0000 (10:45 -0800)
committerJim Meyering <meyering@fb.com>
Tue, 29 Nov 2016 18:57:14 +0000 (10:57 -0800)
This would infloop: echo cx | LC_ALL=C grep -E 'c\b[x ]'
* lib/dfa.c (dfastate): When constructing a new state table, we could
initially declare that we had found a match, and later find that
constraints eliminate that possibility, yet continue to use the
now stale "matched" indicator.  That would lead to an infinite loop.
The solution is to update "matched" when necessary.
Introduced by commit v0.1-983-g403adf1.

ChangeLog
lib/dfa.c

index fd062aee7d566515e71df9c012ee3e94208980f4..3b18083882f661f87b390ffe8848b0059392c99b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2016-11-29  Jim Meyering  <meyering@fb.com>
+
+       dfa: avoid new infinite loop
+       This would infloop: echo cx | LC_ALL=C grep -E 'c\b[x ]'
+       * lib/dfa.c (dfastate): When constructing a new state table, we could
+       initially declare that we had found a match, and later find that
+       constraints eliminate that possibility, yet continue to use the
+       now stale "matched" indicator.  That would lead to an infinite loop.
+       The solution is to update "matched" when necessary.
+       Introduced by commit v0.1-983-g403adf1.
+
 2016-11-27  Norihiro Tanaka <noritnk@kcn.ne.jp>
 
         dfa: avoid match middle in multibyte character
index 673ef95d4c509053804c3404f74bb92aee50c54c..0412b2c7ce4c08d8f5b81e93b7f18f90c9e19cee 100644 (file)
--- a/lib/dfa.c
+++ b/lib/dfa.c
@@ -2609,6 +2609,12 @@ dfastate (state_num s, struct dfa *d, unsigned char uc, state_num trans[])
             continue;
           if (j == CHARCLASS_WORDS)
             continue;
+
+          /* If we have reset the bit that made us declare "matched", reset
+             that indicator, too.  This is required to avoid an infinite loop
+             with this command: echo cx | LC_ALL=C grep -E 'c\b[x ]'  */
+          if (!tstbit (uc, matches))
+            matched = false;
         }
 
 #ifdef DEBUG