changeset 38215:1bb896d10746

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.
author Jim Meyering <meyering@fb.com>
date Tue, 29 Nov 2016 10:45:46 -0800
parents 98c3a76378d6
children 06066d898505
files ChangeLog lib/dfa.c
diffstat 2 files changed, 17 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Mon Nov 28 22:26:07 2016 +0900
+++ b/ChangeLog	Tue Nov 29 10:45:46 2016 -0800
@@ -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
--- a/lib/dfa.c	Mon Nov 28 22:26:07 2016 +0900
+++ b/lib/dfa.c	Tue Nov 29 10:45:46 2016 -0800
@@ -2609,6 +2609,12 @@
             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