From 2e75efbf90869abfeafc0ab9fcd4fa4b453c0b2a Mon Sep 17 00:00:00 2001 From: Norihiro Tanaka Date: Sat, 21 Jan 2017 18:01:53 +0900 Subject: [PATCH] grep: fix matching not longest pattern with grep -Fo * src/kwset.c (acexec): Fix it. * tests/fgrep-longest: New test. * tests/Makefile.am: Add the test. * NEWS: Mention it. --- NEWS | 3 +++ src/kwset.c | 17 ++++++++++++++--- tests/fgrep-longest | 22 ++++++++++++++++++++++ 3 files changed, 39 insertions(+), 3 deletions(-) create mode 100755 tests/fgrep-longest diff --git a/NEWS b/NEWS index 3529f4e..7fcc0b1 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,9 @@ GNU grep NEWS -*- outline -*- ** Bug fixes + grep -Fo no longer matches not longest pattern. + [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 39a1e15..258cff5 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 0000000..c8595a1 --- /dev/null +++ b/tests/fgrep-longest @@ -0,0 +1,22 @@ +#! /bin/sh +# grep -F matches not longest pattern. +# 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 + +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 -- 1.7.1