>From 1d6609c299d2a51747c9bc9e82a399d53c54f8ea Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 31 Jan 2016 23:29:01 -0800 Subject: [PATCH] Omit excess "Binary file ... matches" Problem reported in: http://bugs.gnu.org/22461 * src/grep.c (grep): Don't report "Binary file ... matches" merely because the file contained both matches and binary data. Insist that the binary data contained a match. * tests/null-byte: Add a test for this. --- src/grep.c | 16 +++++++++++----- tests/null-byte | 5 +++++ 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/grep.c b/src/grep.c index 10aabf9..73c3651 100644 --- a/src/grep.c +++ b/src/grep.c @@ -1373,7 +1373,11 @@ grep (int fd, struct stat const *st) char nul_zapper = '\0'; bool done_on_match_0 = done_on_match; bool out_quiet_0 = out_quiet; - bool has_nulls = false; + + /* The value of NLINES when nulls were first deduced in the input; + this is not necessarily the same as the number of matching lines + before the first null. -1 if no input nulls have been deduced. */ + intmax_t nlines_first_null = -1; if (! reset (fd, st)) return 0; @@ -1400,15 +1404,15 @@ grep (int fd, struct stat const *st) for (bool firsttime = true; ; firsttime = false) { - if (!has_nulls && eol && binary_files != TEXT_BINARY_FILES + if (nlines_first_null < 0 && eol && binary_files != TEXT_BINARY_FILES && (buf_has_nulls (bufbeg, buflim - bufbeg) || (firsttime && file_must_have_nulls (buflim - bufbeg, fd, st)))) { - has_nulls = true; if (binary_files == WITHOUT_MATCH_BINARY_FILES) return 0; if (!count_matches) done_on_match = out_quiet = true; + nlines_first_null = nlines; nul_zapper = eol; skip_nuls = skip_empty_lines; } @@ -1445,7 +1449,8 @@ grep (int fd, struct stat const *st) nlines += grepbuf (beg, lim); if (pending) prpending (lim); - if ((!outleft && !pending) || (nlines && done_on_match)) + if ((!outleft && !pending) + || (done_on_match && MAX (0, nlines_first_null) < nlines)) goto finish_grep; } @@ -1490,7 +1495,8 @@ grep (int fd, struct stat const *st) finish_grep: done_on_match = done_on_match_0; out_quiet = out_quiet_0; - if ((has_nulls || encoding_error_output) && !out_quiet && nlines != 0) + if (!out_quiet && (encoding_error_output + || (0 <= nlines_first_null && nlines_first_null < nlines))) { printf (_("Binary file %s matches\n"), filename); if (line_buffered) diff --git a/tests/null-byte b/tests/null-byte index 44dad92..9a76887 100755 --- a/tests/null-byte +++ b/tests/null-byte @@ -51,4 +51,9 @@ for left in '' a '#' '\0'; do done done +(echo xxx && yes yyy | sed 100000q && printf '\0') >in || framework_failure_ +echo xxx >exp || framework_failure_ +grep xxx in >out || fail=1 +compare exp out || fail=1 + Exit $fail -- 2.5.0