diff options
author | Norihiro Tanaka <noritnk@kcn.ne.jp> | 2014-11-12 22:25:18 +0900 |
---|---|---|
committer | Jim Meyering <meyering@fb.com> | 2014-11-14 08:18:31 -0800 |
commit | 0d86051ae82cfc1b24bd28ac470ae67ca545ec9f (patch) | |
tree | c79176a0bff0e0b467e2d865b0c98cb5bcae1372 | |
parent | d48e658e03a70ff648801cbea698c11abff80016 (diff) | |
download | grep-0d86051ae82cfc1b24bd28ac470ae67ca545ec9f.tar.gz |
grep -F -x -o PAT would print an extra newline for each match
* src/kwsearch.c (Fexecute): Correctly compute the length of a match
by subtracting 2 (not 1) when match_lines is set. With -x, we augment
the "line" by both prepending and appending an EOLBYTE to the search
pattern. Here, we must correct for that. However, to compensate,
when we are using -x (--line-regexp) and start_ptr is NULL, we have
to add 1 to the length so that we still print the trailing EOLBYTE.
Introduced by commit v2.18-85-g2c94326.
* tests/match-lines: Add a new test.
* tests/Makefile.am (TESTS): Add it.
* NEWS (Bug fixes): Mention it.
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | src/kwsearch.c | 7 | ||||
-rw-r--r-- | tests/Makefile.am | 1 | ||||
-rwxr-xr-x | tests/match-lines | 36 |
4 files changed, 45 insertions, 2 deletions
@@ -41,6 +41,9 @@ GNU grep NEWS -*- outline -*- implying that the match, "10" was on line 1. [bug introduced in grep-2.19] + grep -F -x -o no longer prints an extra newline for each match. + [bug introduced in grep-2.19] + grep in a non-UTF8 multibyte locale could mistakenly match in the middle of a multibyte character when using a '^'-anchored alternate in a pattern, leading it to print non-matching lines. [bug present since "the beginning"] diff --git a/src/kwsearch.c b/src/kwsearch.c index 6bd516a9..aa965f62 100644 --- a/src/kwsearch.c +++ b/src/kwsearch.c @@ -129,7 +129,7 @@ Fexecute (char const *buf, size_t size, size_t *match_size, buf + size - beg + match_lines, &kwsmatch); if (offset == (size_t) -1) goto failure; - len = kwsmatch.size[0] - match_lines; + len = kwsmatch.size[0] - 2 * match_lines; if (!match_lines && MB_CUR_MAX > 1 && !using_utf8 () && mb_goback (&mb_start, beg + offset, buf + size) != 0) { @@ -142,7 +142,10 @@ Fexecute (char const *buf, size_t size, size_t *match_size, if (start_ptr && !match_words) goto success_in_beg_and_len; if (match_lines) - goto success_in_beg_and_len; + { + len += start_ptr == NULL; + goto success_in_beg_and_len; + } if (match_words) for (try = beg; ; ) { diff --git a/tests/Makefile.am b/tests/Makefile.am index c006e582..217a731f 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -73,6 +73,7 @@ TESTS = \ invalid-multibyte-infloop \ khadafy \ long-line-vs-2GiB-read \ + match-lines \ max-count-overread \ max-count-vs-context \ mb-dot-newline \ diff --git a/tests/match-lines b/tests/match-lines new file mode 100755 index 00000000..51c039e9 --- /dev/null +++ b/tests/match-lines @@ -0,0 +1,36 @@ +#!/bin/sh +# Trigger a bug in the DFA matcher that would make +# grep -F -x -o PAT print an extra newline for each match. +# This would fail for grep-2.19 and grep-2.20. + +# Copyright 2014 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +. "${srcdir=.}/init.sh"; path_prepend_ ../src + +printf 'a\n' > in || framework_failure_ + +fail=0 + +for locale in C en_US.UTF-8; do + for options in -x '-E -x' '-F -x'; do + for o in '' -o; do + LC_ALL=$locale grep $o $options a in > out || fail=1 + compare out in || fail=1 + done + done +done + +Exit $fail |