* zdiff.in: Fix typo that broke most usages. Problem reported by
authorPaul Eggert <eggert@cs.ucla.edu>
Sun, 24 Dec 2006 04:14:57 +0000 (04:14 +0000)
committerPaul Eggert <eggert@cs.ucla.edu>
Sun, 24 Dec 2006 04:14:57 +0000 (04:14 +0000)
Jari Aalto in <http://bugs.debian.org/404114>.  While we're at it,
fix a bunch of other problems.  Handle "-" better.  Send
diagnostics to stderr, not stdout.  Use expr rather than echo |
sed, to handle special characters better.  Report a diagnostic in
the 1-arg case, if the argument doesn't end in .gz or the like,
rather than having incomprehensible behavior.  Do not require that
the inputs be regular files.  Avoid creating a temporary entirely,
if /dev/fd works.  If not, then resist denial-of-service attacks
better, by using mktemp.
* Makefile.am (gzip.doc.gz): New rule.
(check-local): Depend on it, and test zdiff for Debian bug 404114.

ChangeLog
Makefile.am
zdiff.in

index 1536e72430ca46594344a3ae11890c2aeac921fe..1ba9221f0948793f4e72cc242bff84292e2ead08 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2006-12-23  Paul Eggert  <eggert@cs.ucla.edu>
+
+       * zdiff.in: Fix typo that broke most usages.  Problem reported by
+       Jari Aalto in <http://bugs.debian.org/404114>.  While we're at it,
+       fix a bunch of other problems.  Handle "-" better.  Send
+       diagnostics to stderr, not stdout.  Use expr rather than echo |
+       sed, to handle special characters better.  Report a diagnostic in
+       the 1-arg case, if the argument doesn't end in .gz or the like,
+       rather than having incomprehensible behavior.  Do not require that
+       the inputs be regular files.  Avoid creating a temporary entirely,
+       if /dev/fd works.  If not, then resist denial-of-service attacks
+       better, by using mktemp.
+       * Makefile.am (gzip.doc.gz): New rule.
+       (check-local): Depend on it, and test zdiff for Debian bug 404114.
+
 2006-12-22  Paul Eggert  <eggert@cs.ucla.edu>
 
        * zdiff.1: Mention that these programs currently understand only
index 917641d4ee042642651c2b32a8df393f03787827..6a72aeea7199f3dbcffdbaf7e78faa93e624108e 100644 (file)
@@ -48,6 +48,9 @@ gzip_LDADD = lib/libgzip.a
 gzip.doc: gzip.1
        groff -man -Tascii $(srcdir)/gzip.1 | col -b | uniq >$@
 
+gzip.doc.gz: gzip.doc
+       gzip <$? >$@
+
 SUFFIXES = .in
 .in:
        sed \
@@ -60,7 +63,12 @@ SUFFIXES = .in
 # A simple test, just of gzip -- more of a sanity check than anything else.
 FILES_TO_CHECK = $(bin_SCRIPTS) $(gzip_LDADD) \
   $(top_srcdir)/ChangeLog $(top_srcdir)/configure $(top_srcdir)/gzip.c
-check-local: $(FILES_TO_CHECK)
+check-local: $(FILES_TO_CHECK) gzip.doc.gz
+       ./zdiff -c gzip.doc.gz
+       ./zdiff -c gzip.doc gzip.doc
+       ./zdiff gzip.doc gzip.doc.gz
+       ./zdiff -c - gzip.doc <gzip.doc.gz
+       ./zdiff -c gzip.doc.gz gzip.doc.gz
        for file in $(FILES_TO_CHECK); do \
          ./gzip -cv -- "$$file" | ./gzip -d | cmp - "$$file" || exit; \
        done
@@ -96,7 +104,7 @@ install-exec-hook remove-installed-links:
 
 uninstall-local: remove-installed-links
 
-MAINTAINERCLEANFILES = gzip.doc
+MAINTAINERCLEANFILES = gzip.doc gzip.doc.gz
 
 MOSTLYCLEANFILES = _match.i match_.s _match.S \
   gzexe zdiff zforce zgrep zless zmore znew
index 6194cf914176d1f60c9be6c07e97d9e5917a1860..74c92fb7a4f3afd0f839856470032d21ab22ca5b 100644 (file)
--- a/zdiff.in
+++ b/zdiff.in
@@ -11,8 +11,8 @@
 
 PATH="BINDIR:$PATH"; export PATH
 case "$0" in
-  *cmp) prog=cmp ; comp=${CMP-cmp}   ;;
-  *)    prog=diff; comp=${DIFF-diff} ;;
+  *cmp) prog=cmp ; cmp='${CMP-cmp}'  ;;
+  *)    prog=diff; cmp='${DIFF-diff}';;
 esac
 
 version="z$prog (gzip) @VERSION@
@@ -32,50 +32,72 @@ OPTIONs are the same as for '$prog'.
 
 Report bugs to <bug-gzip@gnu.org>."
 
-OPTIONS=
 FILES=
 while :; do
   case $1 in
   --h*) echo "$usage" || exit 2; exit;;
   --v*) echo "$version" || exit 2; exit;;
   --) shift; break;;
-  -*) OPTIONS="$OPTIONS $ARG"; shift;;
+  -*\'*) echo >&2 "$prog: $1: option contains apostrophe"; exit 2;;
+  -?*) cmp="$cmp '$1'"; shift;;
+  *) break;;
   esac
 done
+cmp="$cmp --"
+
 for file; do
-  test -f "$file" || {
-    echo "$prog: $file not found or not a regular file"
-    exit 2
-  }
+  test "X$file" = X- || <"$file" || exit 2
 done
-if test $# -eq 1; then
-       FILE=`echo "$1" | sed 's/[-.][zZtga]*$//'`
-       gzip -cd -- "$1" | $comp $OPTIONS - "$FILE"
 
+if test $# -eq 1; then
+  case $1 in
+  *[-.]gz* | *[-.][zZ] | *.t[ga]z)
+    FILE=`expr "X$1" : 'X\(.*\)[-.][zZtga]*$'`
+    gzip -cd -- "$1" | eval "$cmp" - '"$FILE"';;
+  *)
+    echo >&2 "$prog: $1: unknown compressed file extension"
+    exit 2;;
+  esac
 elif test $# -eq 2; then
        case "$1" in
-        *[-.]gz* | *[-.][zZ] | *.t[ga]z)
+       *[-.]gz* | *[-.][zZ] | *.t[ga]z | -)
                 case "$2" in
-               *[-.]gz* | *[-.][zZ] | *.t[ga]z)
-                       F=`echo "$2" | sed 's|.*/||;s|[-.][zZtga]*||'`
-                       set -C
-                       trap 'rm -f /tmp/"$F".$$; exit 2' HUP INT PIPE TERM 0
-                       gzip -cdfq -- "$2" > /tmp/"$F".$$ || exit
-                       gzip -cdfq -- "$1" | $comp $OPTIONS - /tmp/"$F".$$
+               *[-.]gz* | *[-.][zZ] | *.t[ga]z | -)
+                   if test "$1$2" = --; then
+                       gzip -cdfq - | eval "$cmp" - -
+                   elif test -r /dev/fd/3 3</dev/null; then
+                       gzip -cdfq -- "$1" |
+                         (gzip -cdfq -- "$2" |
+                          eval "$cmp" /dev/fd/3 -) 3<&0
+                   else
+                       F=`expr "/$2" : '.*/\(.*\)[-.][zZtga]*$'` || F=$prog
+                       tmp=
+                       trap '
+                         test -n "$tmp" && rm -f "$tmp"
+                         (exit 2); exit 2
+                       ' HUP INT PIPE TERM 0
+                       if type mktemp >/dev/null 2>&1; then
+                         tmp=`mktemp -t -- "$F.XXXXXX"` || exit
+                       else
+                         set -C
+                         tmp=${TMPDIR-/tmp}/$F.$$
+                       fi
+                       gzip -cdfq -- "$2" > "$tmp" || exit
+                       gzip -cdfq -- "$1" | eval "$cmp" - '"$tmp"'
                         STAT="$?"
-                       /bin/rm -f /tmp/"$F".$$ || STAT=2
+                       rm -f "$tmp" || STAT=2
                        trap - HUP INT PIPE TERM 0
-                       exit $STAT;;
-
-               *)      gzip -cdfq -- "$1" | $comp $OPTIONS - "$2";;
+                       exit $STAT
+                   fi;;
+               *)      gzip -cdfq -- "$1" | eval "$cmp" - '"$2"';;
                 esac;;
         *)      case "$2" in
-               *[-.]gz* | *[-.][zZ] | *.t[ga]z)
-                       gzip -cdfq -- "$2" | $comp $OPTIONS "$1" -;;
-                *)      $comp $OPTIONS "$1" "$2";;
+               *[-.]gz* | *[-.][zZ] | *.t[ga]z | -)
+                       gzip -cdfq -- "$2" | eval "$cmp" '"$1"' -;;
+               *)      eval "$cmp" '"$1"' '"$2"';;
                 esac;;
        esac
 else
-       echo "$usage"
+       echo >&2 "$usage"
        exit 2
 fi