From bb184b98c27fa46826eaa2f6272cb4d6eacc75a8 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 8 Mar 2022 13:02:37 -0800 Subject: [PATCH] zdiff: fix another arg-handling bug Also allow args after file names. Problem reported by Lv Ying . --- zdiff.in | 127 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 75 insertions(+), 52 deletions(-) diff --git a/zdiff.in b/zdiff.in index d982d9f..593cb6e 100644 --- a/zdiff.in +++ b/zdiff.in @@ -48,60 +48,85 @@ escape=' $s/X$/'\''/ ' -while :; do - argdone=: - case $1 in +filesonly= +file1= +file2= +needop= + +for arg +do + case $filesonly$needop$arg in --h*) printf '%s\n' "$usage" || exit 2; exit;; --v*) printf '%s\n' "$version" || exit 2; exit;; - --) shift; break;; - -*\'*) argdone=false arg=$1;; - -[CDFISUWXx]) - cmp="$cmp $1" - case ${2?} in - -*\'*) argdone=false arg=$2;; - *) cmp="$cmp '$2'";; - esac - shift;; - -?*) cmp="$cmp '$1'";; - *) break;; + --) filesonly=t;; + -*\'*) cmp="$cmp '"`printf '%sX\n' "$arg" | sed "$escape"`;; + -[CDFISUWXx]) needop="'$arg'";; + -?*) cmp="$cmp '$arg'";; + *) case $needop in + '') case $arg in + '') printf >&2 '%s\n' "$0: empty file name"; exit 2;; + esac + case $file1 in + '') file1=$arg;; + *) case $file2 in + '') file2=$arg;; + *) printf >&2 '%s\n' "$0: extra operand '$arg'"; exit 2;; + esac;; + esac;; + *) cmp="$cmp $needop '$arg'" + needop=;; + esac;; esac - $argdone || cmp="$cmp '"`printf '%sX\n' "$arg" | sed "$escape"` - shift done +case $needop in +'') ;; +*) printf >&2 '%s\n' "$0: $prevarg: option requires an argument -- $needop" + exit 2;; +esac + cmp="$cmp --" -for file -do - test "X$file" = X- || <"$file" || exit 2 -done +case $file1 in +'') printf >&2 '%s\n' "$0: missing operand"; exit 2;; +-) ;; +*) <"$file1" || exit 2;; +esac +case $file2 in +''|-) ;; +*) <"$file2" || exit 2;; +esac gzip_status=0 exec 3>&1 -if test $# -eq 1; then - case $1 in +case $file2 in +'') + case $file1 in *[-.]gz* | *[-.][zZ] | *.t[ga]z) - FILE=`expr "X$1" : 'X\(.*\)[-.][zZtga]*$'` + FILE=`expr "X$file1" : 'X\(.*\)[-.][zZtga]*$'` gzip_status=$( exec 4>&1 - (gzip -cd -- "$1" 4>&-; echo $? >&4) 3>&- | eval "$cmp" - '"$FILE"' >&3 + (gzip -cd -- "$file1" 4>&-; echo $? >&4) 3>&- | + eval "$cmp" - '"$FILE"' >&3 );; *) - printf >&2 '%s\n' "$0: $1: unknown compressed file extension" + printf >&2 '%s\n' "$0: $file1: unknown compressed file extension" exit 2;; - esac -elif test $# -eq 2; then - case "$1" in + esac;; +*) + case $file1,$file2 in + -,-) + gzip_status=$( + exec 4>&1 + (gzip -cdfq - 4>&-; echo $? >&4) 3>&- | + eval "$cmp" - - >&3 + );; + *) + case $file1 in *[-.]gz* | *[-.][zZ] | *.t[ga]z | -) - case "$2" in + case $file2 in *[-.]gz* | *[-.][zZ] | *.t[ga]z | -) - if test "$1$2" = --; then - gzip_status=$( - exec 4>&1 - (gzip -cdfq - 4>&-; echo $? >&4) 3>&- | - eval "$cmp" - - >&3 - ) - elif + if # Reject Solaris 8's buggy /bin/bash 2.03. echo X | (echo X | eval "$cmp" /dev/fd/5 - >/dev/null 2>&1) \ @@ -109,8 +134,9 @@ elif test $# -eq 2; then then gzip_status=$( exec 4>&1 - (gzip -cdfq -- "$1" 4>&-; echo $? >&4) 3>&- | - ( (gzip -cdfq -- "$2" 4>&-; echo $? >&4) 3>&- 5<&- &-; echo $? >&4) 3>&- | + ((gzip -cdfq -- "$file2" 4>&- + echo $? >&4) 3>&- 5<&- &3) 5<&0 ) cmp_status=$? @@ -137,10 +163,10 @@ elif test $# -eq 2; then set -C tmp=${TMPDIR}zdiff$$ fi - gzip -cdfq -- "$2" > "$tmp" || exit 2 + gzip -cdfq -- "$file2" > "$tmp" || exit 2 gzip_status=$( exec 4>&1 - (gzip -cdfq -- "$1" 4>&-; echo $? >&4) 3>&- | + (gzip -cdfq -- "$file1" 4>&-; echo $? >&4) 3>&- | eval "$cmp" - '"$tmp"' >&3 ) cmp_status=$? @@ -151,25 +177,22 @@ elif test $# -eq 2; then *) gzip_status=$( exec 4>&1 - (gzip -cdfq -- "$1" 4>&-; echo $? >&4) 3>&- | - eval "$cmp" - '"$2"' >&3 + (gzip -cdfq -- "$file1" 4>&-; echo $? >&4) 3>&- | + eval "$cmp" - '"$file2"' >&3 );; esac;; - *) case "$2" in + *) case $file2 in *[-.]gz* | *[-.][zZ] | *.t[ga]z | -) gzip_status=$( exec 4>&1 - (gzip -cdfq -- "$2" 4>&-; echo $? >&4) 3>&- | - eval "$cmp" '"$1"' - >&3 + (gzip -cdfq -- "$file2" 4>&-; echo $? >&4) 3>&- | + eval "$cmp" '"$file1"' - >&3 );; - *) eval "$cmp" '"$1"' '"$2"';; + *) eval "$cmp" '"$file1"' '"$file2"';; esac;; - esac -else - printf >&2 '%s\n' \ - "$0: invalid number of operands; try \`$0 --help' for help" - exit 2 -fi + esac;; + esac;; +esac cmp_status=$? test "$gzip_status" -eq 0 || exit 2 -- 2.35.1