From: Jim Meyering Date: Tue, 29 Nov 2016 18:45:46 +0000 (-0800) Subject: dfa: avoid new infinite loop X-Git-Tag: v1.0~6523 X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=ca3ca77fc9e497ff5048a9f1ee0d1acc8e050f51;p=gnulib.git 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. --- diff --git a/ChangeLog b/ChangeLog index fd062aee7d..3b18083882 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2016-11-29 Jim Meyering + + 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 dfa: avoid match middle in multibyte character diff --git a/lib/dfa.c b/lib/dfa.c index 673ef95d4c..0412b2c7ce 100644 --- 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