bug-gzip
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Bug#404114: gzip: [zdiff] Infine loop in "while : do .. case $1 esac


From: Paul Eggert
Subject: Re: Bug#404114: gzip: [zdiff] Infine loop in "while : do .. case $1 esac done"
Date: Sat, 23 Dec 2006 20:17:47 -0800
User-agent: Gnus/5.1008 (Gnus v5.10.8) Emacs/21.4 (gnu/linux)

Thanks for reporting that.  zdiff really is a can of worms.

Can you please try this patch?  I installed it into the main CVS for gzip.

2006-12-23  Paul Eggert  <address@hidden>

        * 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.

--- zdiff.in    9 Dec 2006 04:25:56 -0000       1.5
+++ zdiff.in    24 Dec 2006 04:13:56 -0000
@@ -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 <address@hidden>."

-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
--- Makefile.am 15 Dec 2006 08:25:02 -0000      1.17
+++ Makefile.am 24 Dec 2006 04:13:56 -0000
@@ -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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]