bug-bash
[Top][All Lists]
Advanced

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

Re: foo=$*: ^A and DEL are prefixed or removed


From: Martijn Dekker
Subject: Re: foo=$*: ^A and DEL are prefixed or removed
Date: Sun, 17 Dec 2017 22:09:33 +0000
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:52.0) Gecko/20100101 Thunderbird/52.5.0

Op 16-12-17 om 17:06 schreef Chet Ramey:
> On 11/24/17 3:17 AM, Martijn Dekker wrote:
>> Here's another corner-case bug with assigning $* to a variable (i.e.:
>> foo=$*). If IFS is empty, the $* expansion removes any $'\001' (^A) and
>> $'\177' (DEL) characters. If IFS contains a value, each ^A and DEL
>> character is prefixed by another $'\001'. If IFS is unset, the bug does
>> not show up at all.
> 
> Thanks for the report. I'll fix this for the next version.

FWIW, here's a test script. It's POSIX compatible so you can compare
with other shells. Correct output is
        soh stx etx del   / soh stx etx del
for all cases.

- M.

defaultIFS=$IFS
set -o errexit -o noglob
(set -o pipefail) 2>/dev/null && set -o pipefail
teststring=$(printf '\1\2\3\177')
n=0

trim_od() {
        od -a | sed -n '1 { s/^0*[[:blank:]]*//; s/[[:blank:]]*$//; p; }'
}

doTest() {
        set -- "$teststring"
        eval "$testcmd"
        case ${IFS+s}${IFS:+n} in
        ( sn )  i=$(printf %s "$IFS" | trim_od) ;;
        ( s )   i='(null)' ;;
        ( '' )  i='(unset)' ;;
        ( * )   echo 'internal error!' >&2; exit 125 ;;
        esac
        printf '\n%03d: IFS = %s: %s\n' "$((n+=1))" "$i" "$testcmd"
        printf %s "$*${foo+/}${foo-}" | trim_od
}

doAllTests() {
        for testcmd in \
                'unset -v foo; set -- ${foo=$*}' \
                'unset -v foo; set -- ${foo="$*"}' \
                'unset -v foo; set -- "${foo=$*}"' \
                \
                'foo=; set -- ${foo:=$*}' \
                'foo=; set -- ${foo:="$*"}' \
                'foo=; set -- "${foo:=$*}"' \
                \
                'unset -v foo; set -- ${foo=$@}' \
                'unset -v foo; set -- ${foo="$@"}' \
                'unset -v foo; set -- "${foo=$@}"' \
                \
                'foo=; set -- ${foo:=$@}' \
                'foo=; set -- ${foo:="$@"}' \
                'foo=; set -- "${foo:=$@}"'
        do
                doTest "$testcmd"
        done
}

unset -v IFS; doAllTests
IFS=''; doAllTests
IFS='x'; doAllTests
IFS=$defaultIFS; doAllTests



reply via email to

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