On 2021-01-08 Lasse Collin wrote:
> It's tempting to ignore exit statuses >= 128 at the end of the script
> where it current checks for "$xz_status" -eq 0 but that doesn't work
> because in the middle of the script there is also this:
> 
>             case $xz_status in
>               *[1-9]*) xz_status=1;;
>               *) xz_status=0;;
>             esac
> 
> There xz_status contains two numbers and the "case" finds out if they
> are both zero. Perhaps this "case" should be replaced with something
> more sophisticated that checks both numbers separately and ignores
> values >= 128.

I found it easy to change the above "case" and ignore >= 128 at the
bottom of the script. But that still isn't enough.

gzip -q turns SIGPIPE into exit status of 2. Ignoring 2 would work for
gzip but that is incompatible with bzip2 which uses exit status 2 to
indicate corrupt input. Trying to handle exit statuses separately for
each compressor is complicated because two different tools may be in
use at the same time. Getting rid of gzip -q sounds more reasonable.

The script uses -cdfq to decompress and I'm not sure why the -q is
there. There is an exception when only one argument is given, then -cd
is used. The -f option is needed with xz (and it's fine with gzip too)
to handle uncompressed files: xz -cdf or gzip -cdf with unknown file
format behaves like cat and just copies the input to the output. The
use of -f (and the non-use in the single-file case) looks fine, but I
don't know what to think about -q. Perhaps it hides warnings in some
rare cases where they aren't wanted.

The following patch replace -cdfq with -cdf and ignores decompressor
exit statuses >= 128. Could someone test if it fixes the original bug
without introducing any obvious new bugs with some of the supported
compression tools?

diff --git a/src/scripts/xzdiff.in b/src/scripts/xzdiff.in
index eb7825c..b285572 100644
--- a/src/scripts/xzdiff.in
+++ b/src/scripts/xzdiff.in
@@ -116,23 +116,17 @@ elif test $# -eq 2; then
           if test "$1$2" = --; then
             xz_status=$(
               exec 4>&1
-              ($xz1 -cdfq - 4>&-; echo $? >&4) 3>&- |
+              ($xz1 -cdf - 4>&-; echo $? >&4) 3>&- |
                 eval "$cmp" - - >&3
             )
           elif # Reject Solaris 8's buggy /bin/bash 2.03.
               echo X | (echo X | eval "$cmp" /dev/fd/5 - >/dev/null 2>&1) 
5<&0; then
             xz_status=$(
               exec 4>&1
-              ($xz1 -cdfq -- "$1" 4>&-; echo $? >&4) 3>&- |
-                ( ($xz2 -cdfq -- "$2" 4>&-; echo $? >&4) 3>&- 5<&- </dev/null |
+              ($xz1 -cdf -- "$1" 4>&-; echo $? >&4) 3>&- |
+                ( ($xz2 -cdf -- "$2" 4>&-; echo $? >&4) 3>&- 5<&- </dev/null |
                 eval "$cmp" /dev/fd/5 - >&3) 5<&0
             )
-            cmp_status=$?
-            case $xz_status in
-              *[1-9]*) xz_status=1;;
-              *) xz_status=0;;
-            esac
-            (exit $cmp_status)
           else
             F=`expr "/$2" : '.*/\(.*\)[-.][ablmotxz2]*$'` || F=$prog
             tmp=
@@ -161,10 +155,10 @@ elif test $# -eq 2; then
               mkdir -- "${TMPDIR-/tmp}/$prog.$$" || exit 2
               tmp="${TMPDIR-/tmp}/$prog.$$"
             fi
-            $xz2 -cdfq -- "$2" > "$tmp/$F" || exit 2
+            $xz2 -cdf -- "$2" > "$tmp/$F" || exit 2
             xz_status=$(
               exec 4>&1
-              ($xz1 -cdfq -- "$1" 4>&-; echo $? >&4) 3>&- |
+              ($xz1 -cdf -- "$1" 4>&-; echo $? >&4) 3>&- |
                 eval "$cmp" - '"$tmp/$F"' >&3
             )
             cmp_status=$?
@@ -175,7 +169,7 @@ elif test $# -eq 2; then
       *)
         xz_status=$(
           exec 4>&1
-          ($xz1 -cdfq -- "$1" 4>&-; echo $? >&4) 3>&- |
+          ($xz1 -cdf -- "$1" 4>&-; echo $? >&4) 3>&- |
             eval "$cmp" - '"$2"' >&3
         );;
     esac;;
@@ -184,7 +178,7 @@ elif test $# -eq 2; then
       *[-.][zZ] | *_z | *[-.][gx]z | *[-.]bz2 | *[-.]lzma | *.t[abglx]z | 
*.tbz2 | *[-.]lzo | *.tzo | -)
         xz_status=$(
           exec 4>&1
-          ($xz2 -cdfq -- "$2" 4>&-; echo $? >&4) 3>&- |
+          ($xz2 -cdf -- "$2" 4>&-; echo $? >&4) 3>&- |
             eval "$cmp" '"$1"' - >&3
          );;
       *)
@@ -197,5 +191,9 @@ else
 fi
 
 cmp_status=$?
-test "$xz_status" -eq 0 || exit 2
+for num in $xz_status ; do
+  test "$num" -eq 0 && continue
+  test "$num" -ge 128 && continue
+  exit 2
+done
 exit $cmp_status

-- 
Lasse Collin  |  IRC: Larhzu @ IRCnet & Freenode

Reply via email to