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
