I found this bug while working on the hang. I thought it could be fixed only by almost-rewriting Fexecute, but this doesn't seem true.
Additional pairs of eyes are very welcome. Paolo Bonzini (2): grep: fix matching the empty string with grep -Fw test: cover just-fixed bug NEWS | 3 +++ src/kwsearch.c | 4 +++- tests/empty | 4 +--- 3 files changed, 7 insertions(+), 4 deletions(-) >From c922b8607950b538e205700fd850c81feb31c683 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini <[email protected]> Date: Wed, 31 Mar 2010 10:22:46 +0200 Subject: [PATCH 1/2] grep: fix matching the empty string with grep -Fw * NEWS: Document fix. * src/kwsearch.c (Fexecute): The empty string is a valid match if it is a whole word. --- NEWS | 3 +++ src/kwsearch.c | 4 +++- 2 files changed, 6 insertions(+), 1 deletions(-) diff --git a/NEWS b/NEWS index eb94184..1c2f7f3 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,9 @@ GNU grep NEWS -*- outline -*- Searching with grep -F for an empty string in a multibyte locale would hang grep. [bug introduced in 2.6.2] + Searching with grep -Fw for an empty string would not match an + empty line. [bug present since "the beginning"] + PCRE support is once again detected on systems with <pcre/pcre.h> [bug introduced in 2.6.2] diff --git a/src/kwsearch.c b/src/kwsearch.c index 973eb60..45d8dc1 100644 --- a/src/kwsearch.c +++ b/src/kwsearch.c @@ -133,12 +133,14 @@ Fexecute (char const *buf, size_t size, size_t *match_size, goto success; } else if (match_words) - for (try = beg; len; ) + for (try = beg; ; ) { if (try > buf && WCHAR((unsigned char) try[-1])) break; if (try + len < buf + size && WCHAR((unsigned char) try[len])) { + if (!len) + break; offset = kwsexec (kwset, beg, --len, &kwsmatch); if (offset == (size_t) -1) break; -- 1.6.6.1 >From 86cdd51eec00cf1ecc239531c51522b4dfacaf90 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini <[email protected]> Date: Wed, 31 Mar 2010 10:24:21 +0200 Subject: [PATCH 2/2] test: cover just-fixed bug * tests/empty: Test -Fw too. --- tests/empty | 4 +--- 1 files changed, 1 insertions(+), 3 deletions(-) diff --git a/tests/empty b/tests/empty index 9e8f335..d3058f1 100755 --- a/tests/empty +++ b/tests/empty @@ -54,9 +54,7 @@ for locale in C en_US.UTF-8; do fi done - # -F -w omitted because it fails test #6, will be revisited after 2.6 - # stabilizes. - for options in '-E -w' '-E -x' '-E -w -x' '-F -x' '-F -w -x'; do + for options in '-E -w' '-E -x' '-E -w -x' '-F -w' '-F -x' '-F -w -x'; do # should return 0 found a match echo "" | LC_ALL=$locale timeout 10s grep $options -e '' -- 1.6.6.1
