diff options
author | Norihiro Tanaka <noritnk@kcn.ne.jp> | 2017-01-21 18:01:53 +0900 |
---|---|---|
committer | Jim Meyering <meyering@fb.com> | 2017-01-21 08:03:20 -0800 |
commit | b0cdf48d416b2cbb028a1b65c758035ba7c8a2aa (patch) | |
tree | 57f19acee0c29603f5ede6e1665d60b4aed5c850 | |
parent | b408bcee1e81a2c4cc187d520b1fd5ae0da68f13 (diff) | |
download | grep-b0cdf48d416b2cbb028a1b65c758035ba7c8a2aa.tar.gz |
grep -Fo could report a match that is not the longest
* src/kwset.c (acexec): Fix it.
* tests/fgrep-longest: New test.
* tests/Makefile.am: Add the test.
* NEWS: Mention it.
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | src/kwset.c | 17 | ||||
-rwxr-xr-x | tests/fgrep-longest | 23 |
3 files changed, 41 insertions, 3 deletions
@@ -4,6 +4,10 @@ GNU grep NEWS -*- outline -*- ** Bug fixes + When grep -Fo finds matches of differing length, it could + mistakenly print a shorter one. Now it prints a longest one. + [bug introduced in grep-2.26] + When standard output is /dev/null, grep no longer fails when standard input is a file in the Linux /proc file system, or when standard input is a pipe and standard output is in append mode. diff --git a/src/kwset.c b/src/kwset.c index 39a1e157..258cff53 100644 --- a/src/kwset.c +++ b/src/kwset.c @@ -848,9 +848,20 @@ acexec_trans (kwset_t kwset, char const *text, ptrdiff_t len, struct trie const *accept1; char const *left1; unsigned char c = tr (trans, *tp++); - tree = trie->links; - while (tree && c != tree->label) - tree = c < tree->label ? tree->llink : tree->rlink; + while (true) + { + tree = trie->links; + while (tree && c != tree->label) + tree = c < tree->label ? tree->llink : tree->rlink; + if (tree) + break; + trie = trie->fail; + if (!trie) + break; + left1 = tp - trie->depth; + if (left1 > left) + break; + } if (!tree) break; trie = tree->trie; diff --git a/tests/fgrep-longest b/tests/fgrep-longest new file mode 100755 index 00000000..5974d113 --- /dev/null +++ b/tests/fgrep-longest @@ -0,0 +1,23 @@ +#! /bin/sh +# With multiple matches, grep -Fo could print a shorter one. +# This bug affected grep versions 2.26 through 2.27. +# +# Copyright (C) 2017 Free Software Foundation, Inc. +# +# Copying and distribution of this file, with or without modification, +# are permitted in any medium without royalty provided the copyright +# notice and this notice are preserved. + +. "${srcdir=.}/init.sh"; path_prepend_ ../src + +fail=0 + +# The erroneous versions would print "c", rather than the longer match, "bce". +printf 'abce\n' > in || framework_failure_ +printf 'abcd\nc\nbce\n' > pat || framework_failure_ +printf 'bce\n' > exp || framework_failure_ + +LC_ALL=C grep -Fof pat in > out || fail=1 +compare exp out || fail=1 + +Exit $fail |