From 9d3248751178939713a39115cf68ec8a11506cc9 Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Tue, 5 Apr 2022 15:16:33 -0700
Subject: [PATCH 7/7] zgrep: fix "binary file matches" mislabeling
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Problem reported by Jim Avera (Bug#31280).
This became more of an issue when GNU grep 3.5 (2020) started sending
"binary file matches" diagnostics to stderr instead of to stdout.
* tests/Makefile.am (TESTS): Add zgrep-binary.
* tests/zgrep-binary: New test.
* zgrep.in (args): New var, to accumulate args separately
from grep command, so we can prepend args if need be.
Most uses of 'grep' changed to use 'args' instead, or also.
(with_filename): Set to 1 if more than one file and -h not given;
this simplifies later code.
(gnuish_grep): New var; evaluates to true if grep supports
-H and --label options, as is true for GNU and FreeBSD grep.
Append -H to 'grep' if outputting file names with GNUish grep,
and use --label with GNUish grep unless reading from stdin,
as that’s safer and more efficient than relabeling with 'sed'.
---
 NEWS               |  3 +++
 tests/Makefile.am  |  1 +
 tests/zgrep-binary | 30 ++++++++++++++++++++++++++++++
 zgrep.in           | 28 +++++++++++++++++++---------
 4 files changed, 53 insertions(+), 9 deletions(-)
 create mode 100755 tests/zgrep-binary

Index: gzip-1.6/tests/Makefile.am
===================================================================
--- gzip-1.6.orig/tests/Makefile.am
+++ gzip-1.6/tests/Makefile.am
@@ -29,6 +29,7 @@ TESTS =					\
   zdiff					\
   zgrep-f				\
   zgrep-abuse				\
+  zgrep-binary				\
   zgrep-context				\
   zgrep-signal				\
   znew-k
Index: gzip-1.6/tests/zgrep-binary
===================================================================
--- /dev/null
+++ gzip-1.6/tests/zgrep-binary
@@ -0,0 +1,30 @@
+#!/bin/sh
+# 'zgrep PATTERN FILE' would output "(standard input): binary file matches"
+# without mentioning FILE.  Fixed in gzip-1.12.
+
+# Copyright (C) 2022 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 <https://www.gnu.org/licenses/>.
+# limit so don't run it by default.
+
+. "${srcdir=.}/init.sh"; path_prepend_ ..
+
+fail=0
+
+unset GREP_OPTIONS
+
+printf 'foo\0\n' >f || framework_failure_
+LC_ALL=C zgrep foo f >out 2>err && grep '(standard input)' out err && fail=1
+
+Exit $fail
Index: gzip-1.6/zgrep.in
===================================================================
--- gzip-1.6.orig/zgrep.in
+++ gzip-1.6/zgrep.in
@@ -29,6 +29,7 @@ esac
 PATH=$bindir:$PATH
 
 grep='${GREP-'\''@GREP@'\''}'
+args=
 
 version='zgrep (gzip) @VERSION@
 Copyright (C) 2010-2013 Free Software Foundation, Inc.
@@ -154,7 +155,7 @@ while test $# -ne 0; do
     option="'$option'";;
   esac
 
-  grep="$grep $option$optarg"
+  args="$args $option$optarg"
 done
 
 eval "set -- $operands "'${1+"$@"}'
@@ -162,15 +163,23 @@ eval "set -- $operands "'${1+"$@"}'
 if test $have_pat -eq 0; then
   case ${1?"missing pattern; try \`$0 --help' for help"} in
   (*\'*)
-    grep="$grep -- '"$(printf '%s\n' "$1" | LC_ALL=C sed "$escape");;
+    args="$args -- '"$(printf '%s\n' "$1" | LC_ALL=C sed "$escape");;
   (*)
-    grep="$grep -- '$1'";;
+    args="$args -- '$1'";;
   esac
   shift
 fi
 
 if test $# -eq 0; then
   set -- -
+elif test 1 -lt $# && test $no_filename -eq 0; then
+  with_filename=1
+fi
+
+l_e=$(eval "(echo e | $grep -H --label=l e) 2>/dev/null") && test "$l_e" = l:e
+gnuish_grep="test $? -eq 0"
+if $gnuish_grep && test $with_filename -eq 1; then
+  grep="$grep -H"
 fi
 
 exec 3>&1
@@ -197,18 +206,19 @@ do
     exec 5>&1
     ($uncompress -cdfq -- "$i" 5>&-; echo $? >&5) 3>&- |
     if test $files_with_matches -eq 1; then
-      eval "$grep" >/dev/null && { printf '%s\n' "$i" || exit 2; }
+      eval "$grep$args" >/dev/null && { printf '%s\n' "$i" || exit 2; }
     elif test $files_without_matches -eq 1; then
-      eval "$grep" >/dev/null || {
+      eval "$grep$args" >/dev/null || {
         r=$?
         if test $r -eq 1; then
           printf '%s\n' "$i" || r=2
         fi
         exit $r
       }
-    elif test $with_filename -eq 0 &&
-         { test $# -eq 1 || test $no_filename -eq 1; }; then
-      eval "$grep"
+    elif $gnuish_grep && test "$i" != -; then
+      eval "$grep --label \"\$i\"$args"
+    elif $gnuish_grep || test $with_filename -eq 0; then
+      eval "$grep$args"
     else
       case $i in
       (*'
@@ -222,7 +232,7 @@ do
       # Fail if grep or sed fails.
       r=$(
         exec 4>&1
-        (eval "$grep" 4>&-; echo $? >&4) 3>&- |
+        (eval "$grep$args" 4>&-; echo $? >&4) 3>&- |
            LC_ALL=C sed "$sed_script" >&3 4>&-
       ) && exit $r
       r=$?
