mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-02-24 15:04:13 +00:00
The following problems remained:
$ var=x; echo ${var:-'{}'}
x}
$ var=; echo ${var:+'{}'}
}
src/cmd/ksh93/sh/macro.c: varsub():
- Use the new ST_MOD1 state table to skip over ${var-'foo'}, etc.
instead of ST_QUOTE. In ST_MOD1 the ' is categorised as S_LIT
which causes the single quotes to be skipped over correctly.
See d087b031
for more info.
src/cmd/ksh93/tests/quoting2.sh:
- Add tests for this remaining bug.
- Make the new test xtrace-proof.
Resolves: https://github.com/ksh93/ksh/issues/290 (again)
283 lines
10 KiB
Bash
Executable file
283 lines
10 KiB
Bash
Executable file
########################################################################
|
||
# #
|
||
# This software is part of the ast package #
|
||
# Copyright (c) 1982-2011 AT&T Intellectual Property #
|
||
# Copyright (c) 2020-2021 Contributors to ksh 93u+m #
|
||
# and is licensed under the #
|
||
# Eclipse Public License, Version 1.0 #
|
||
# by AT&T Intellectual Property #
|
||
# #
|
||
# A copy of the License is available at #
|
||
# http://www.eclipse.org/org/documents/epl-v10.html #
|
||
# (with md5 checksum b35adb5213ca9657e911e9befb180842) #
|
||
# #
|
||
# Information and Software Systems Research #
|
||
# AT&T Research #
|
||
# Florham Park NJ #
|
||
# #
|
||
# David Korn <dgk@research.att.com> #
|
||
# #
|
||
########################################################################
|
||
|
||
. "${SHTESTS_COMMON:-${0%/*}/_common}"
|
||
|
||
set -o noglob
|
||
if [[ 'hi there' != "hi there" ]]
|
||
then err_exit "single quotes not the same as double quotes"
|
||
fi
|
||
x='hi there'
|
||
if [[ $x != 'hi there' ]]
|
||
then err_exit "$x not the same as 'hi there'"
|
||
fi
|
||
if [[ $x != "hi there" ]]
|
||
then err_exit "$x not the same as \"hi there \""
|
||
fi
|
||
if [[ \a\b\c\*\|\"\ \\ != 'abc*|" \' ]]
|
||
then err_exit " \\ differs from '' "
|
||
fi
|
||
if [[ "ab\'\"\$(" != 'ab\'\''"$(' ]]
|
||
then err_exit " \"\" differs from '' "
|
||
fi
|
||
if [[ $(print -r - 'abc*|" \') != 'abc*|" \' ]]
|
||
then err_exit "\$(print -r - '') differs from ''"
|
||
fi
|
||
if [[ $(print -r - "abc*|\" \\") != 'abc*|" \' ]]
|
||
then err_exit "\$(print -r - '') differs from ''"
|
||
fi
|
||
if [[ "$(print -r - 'abc*|" \')" != 'abc*|" \' ]]
|
||
then err_exit "\"\$(print -r - '')\" differs from ''"
|
||
fi
|
||
if [[ "$(print -r - "abc*|\" \\")" != 'abc*|" \' ]]
|
||
then err_exit "\"\$(print -r - "")\" differs from ''"
|
||
fi
|
||
if [[ $(print -r - "$(print -r - 'abc*|" \')") != 'abc*|" \' ]]
|
||
then err_exit "nested \$(print -r - '') differs from ''"
|
||
fi
|
||
if [[ "$(print -r - $(print -r - 'abc*|" \'))" != 'abc*|" \' ]]
|
||
then err_exit "\"nested \$(print -r - '')\" differs from ''"
|
||
fi
|
||
if [[ $(print -r - "$(print -r - 'abc*|" \')") != 'abc*|" \' ]]
|
||
then err_exit "nested \"\$(print -r - '')\" differs from ''"
|
||
fi
|
||
unset x
|
||
if [[ ${x-$(print -r - "abc*|\" \\")} != 'abc*|" \' ]]
|
||
then err_exit "\${x-\$(print -r - '')} differs from ''"
|
||
fi
|
||
if [[ ${x-$(print -r - "a}c*|\" \\")} != 'a}c*|" \' ]]
|
||
then err_exit "\${x-\$(print -r - '}')} differs from ''"
|
||
fi
|
||
x=$((echo foo)|(cat))
|
||
if [[ $x != foo ]]
|
||
then err_exit "((cmd)|(cmd)) failed"
|
||
fi
|
||
x=$(print -r -- "\"$HOME\"")
|
||
if [[ $x != '"'$HOME'"' ]]
|
||
then err_exit "nested double quotes failed"
|
||
fi
|
||
unset z
|
||
: ${z="a{b}c"}
|
||
if [[ $z != 'a{b}c' ]]
|
||
then err_exit '${z="a{b}c"} not correct'
|
||
fi
|
||
unset z
|
||
: "${z="a{b}c"}"
|
||
if [[ $z != 'a{b}c' ]]
|
||
then err_exit '"${z="a{b}c"}" not correct'
|
||
fi
|
||
if [[ $(print -r -- "a\*b") != 'a\*b' ]]
|
||
then err_exit '$(print -r -- "a\*b") differs from a\*b'
|
||
fi
|
||
unset x
|
||
if [[ $(print -r -- "a\*b$x") != 'a\*b' ]]
|
||
then err_exit '$(print -r -- "a\*b$x") differs from a\*b'
|
||
fi
|
||
x=hello
|
||
set -- ${x+foo bar bam}
|
||
if (( $# !=3 ))
|
||
then err_exit '${x+foo bar bam} does not yield three arguments'
|
||
fi
|
||
set -- ${x+foo "bar bam"}
|
||
if (( $# !=2 ))
|
||
then err_exit '${x+foo "bar bam"} does not yield two arguments'
|
||
fi
|
||
set -- ${x+foo 'bar bam'}
|
||
if (( $# !=2 ))
|
||
then err_exit '${x+foo '\''bar bam'\''} does not yield two arguments'
|
||
fi
|
||
set -- ${x+foo $x bam}
|
||
if (( $# !=3 ))
|
||
then err_exit '${x+foo $x bam} does not yield three arguments'
|
||
fi
|
||
set -- ${x+foo "$x" bam}
|
||
if (( $# !=3 ))
|
||
then err_exit '${x+foo "$x" bam} does not yield three arguments'
|
||
fi
|
||
set -- ${x+"foo $x bam"}
|
||
if (( $# !=1 ))
|
||
then err_exit '${x+"foo $x bam"} does not yield one argument'
|
||
fi
|
||
set -- "${x+foo $x bam}"
|
||
if (( $# !=1 ))
|
||
then err_exit '"${x+foo $x bam}" does not yield one argument'
|
||
fi
|
||
set -- ${x+foo "$x "bam}
|
||
if (( $# !=2 ))
|
||
then err_exit '${x+foo "$x "bam} does not yield two arguments'
|
||
fi
|
||
x="ab$'cd"
|
||
if [[ $x != 'ab$'"'cd" ]]
|
||
then err_exit '$'"' inside double quotes not working"
|
||
fi
|
||
x=`print 'ab$'`
|
||
if [[ $x != 'ab$' ]]
|
||
then err_exit '$'"' inside `` quotes not working"
|
||
fi
|
||
unset a
|
||
x=$(print -r -- "'\
|
||
\
|
||
")
|
||
if [[ $x != "'" ]]
|
||
then err_exit 'line continuation in double strings not working'
|
||
fi
|
||
x=$(print -r -- "'\
|
||
$a\
|
||
")
|
||
if [[ $x != "'" ]]
|
||
then err_exit 'line continuation in expanded double strings not working'
|
||
fi
|
||
x='\*'
|
||
if [[ $(print -r -- $x) != '\*' ]]
|
||
then err_exit 'x="\\*";$x != \*'
|
||
fi
|
||
if [[ $(print -r -- "\}" ) != '\}' ]]
|
||
then err_exit '(print -r -- "\}"' not working
|
||
fi
|
||
if [[ $(print -r -- "\{" ) != '\{' ]]
|
||
then err_exit 'print -r -- "\{"' not working
|
||
fi
|
||
# The following caused a syntax error on earlier versions
|
||
foo=foo x=-
|
||
if [[ `eval print \\${foo$x}` != foo* ]]
|
||
then err_exit '`eval print \\${foo$x}`' not working
|
||
fi
|
||
if [[ "`eval print \\${foo$x}`" != foo* ]]
|
||
then err_exit '"`eval print \\${foo$x}`"' not working
|
||
fi
|
||
if ( [[ $() != '' ]] )
|
||
then err_exit '$() not working'
|
||
fi
|
||
x=a:b:c
|
||
set -- $( IFS=:; print $x)
|
||
if (( $# != 3))
|
||
then err_exit 'IFS not working correctly with command substitution'
|
||
fi
|
||
$SHELL -n 2> /dev/null << \! || err_exit '$(...) bug with ( in comment'
|
||
y=$(
|
||
# ( this line is a bug fix
|
||
print hi
|
||
)
|
||
!
|
||
x=
|
||
for j in glob noglob
|
||
do for i in 'a\*b' 'a\ b' 'a\bc' 'a\*b' 'a\"b'
|
||
do eval [[ '$('print -r -- \'$i\'\$x')' != "'$i'" ]] && err_exit "quoting of $i\$x with $j enabled failed"
|
||
eval [[ '$('print -r -- \'$i\'\${x%*}')' != "'$i'" ]] && err_exit "quoting of $i\${x%*} with $j enabled failed"
|
||
if [[ $j == noglob ]]
|
||
then eval [[ '$('print -r -- \'$i\'\${x:-*}')' != "'$i''*'" ]] && err_exit "quoting of $i\${x:-*} with $j enabled failed"
|
||
fi
|
||
done
|
||
set -f
|
||
done
|
||
foo=foo
|
||
[[ "$" == '$' ]] || err_exit '"$" != $'
|
||
[[ "${foo}$" == 'foo$' ]] || err_exit 'foo=foo;"${foo}$" != foo$'
|
||
[[ "${foo}${foo}$" == 'foofoo$' ]] || err_exit 'foo=foo;"${foo}${foo}$" != foofoo$'
|
||
foo='$ '
|
||
[[ "$foo" == ~(Elr)(\\\$|#)\ ]] || err_exit $'\'$ \' not matching RE \\\\\\$|#\''
|
||
[[ "$foo" == ~(Elr)('\$'|#)\ ]] || err_exit $'\'$ \' not matching RE \'\\$\'|#\''
|
||
foo='# '
|
||
[[ "$foo" == ~(Elr)(\\\$|#)\ ]] || err_exit $'\'# \' not matching RE \\'\$|#\''
|
||
[[ "$foo" == ~(Elr)('\$'|#)\ ]] || err_exit $'\'# \' not matching RE \'\\$\'|#\''
|
||
[[ '\$' == '\$'* ]] || err_exit $'\'\\$\' not matching \'\\$\'*'
|
||
[[ a+a == ~(E)a\+a ]] || err_exit '~(E)a\+a not matching a+a'
|
||
[[ a+a =~ a\+a ]] || err_exit 'RE a\+a not matching a+a'
|
||
|
||
exp='ac'
|
||
got=$'a\0b'c
|
||
[[ $got == "$exp" ]] || err_exit "\$'a\\0b'c expansion failed -- expected '$exp', got '$got'"
|
||
|
||
# ======
|
||
# generating shell-quoted strings using printf %q (same algorithm used for xtrace and output of 'set', 'trap', ...)
|
||
|
||
[[ $(printf '%q\n') == '' ]] || err_exit 'printf "%q" with missing arguments yields non-empty result'
|
||
|
||
# the following fails on 2012-08-01 in UTF-8 locales
|
||
expect="'shell-quoted string'"
|
||
actual=$(
|
||
print -nr $'\303\274' | read -n1 foo # interrupt processing of 2-byte UTF-8 char after reading 1 byte
|
||
printf '%q\n' "shell-quoted string"
|
||
)
|
||
LC_CTYPE=POSIX true # on buggy ksh, a locale re-init via temp assignment restores correct shellquoting
|
||
[[ $actual == "$expect" ]] || err_exit 'shell-quoting corrupted after interrupted processing of UTF-8 char' \
|
||
"(expected $expect; got $actual)"
|
||
|
||
# shell-quoting UTF-8 characters: check for unnecessary encoding
|
||
case ${LC_ALL:-${LC_CTYPE:-${LANG:-}}} in
|
||
( *[Uu][Tt][Ff]8* | *[Uu][Tt][Ff]-8* )
|
||
# must wrap literal UTF-8 characters in 'eval' to avoid syntax error in ja_JP.SJIS
|
||
eval 'expect=$'\''$\'\''عندما يريد العالم أن \\u[202a]يتكلّم \\u[202c] ، فهو يتحدّث بلغة يونيكود.\'\'''\'
|
||
eval 'actual=$(printf %q '\''عندما يريد العالم أن يتكلّم ، فهو يتحدّث بلغة يونيكود.'\'')'
|
||
[[ $actual == "$expect" ]] || err_exit 'shell-quoting: Arabic UTF-8 characters' \
|
||
"(expected $expect; got $actual)"
|
||
eval 'expect="'\''正常終了 正常終了'\''"'
|
||
eval 'actual=$(printf %q '\''正常終了 正常終了'\'')'
|
||
[[ $actual == "$expect" ]] || err_exit 'shell-quoting: Japanese UTF-8 characters' \
|
||
"(expected $expect; got $actual)"
|
||
eval 'expect="'\''aeu aéu'\''"'
|
||
eval 'actual=$(printf %q '\''aeu aéu'\'')'
|
||
[[ $actual == "$expect" ]] || err_exit 'shell-quoting: Latin UTF-8 characters' \
|
||
"(expected $expect; got $actual)"
|
||
expect=$'$\'\\x86\\u[86]\\xf0\\x96v\\xa7\\xb5\''
|
||
actual=$(printf %q $'\x86\u86\xF0\x96\x76\xA7\xB5')
|
||
[[ $actual == "$expect" ]] || err_exit 'shell-quoting: invalid UTF-8 characters not encoded with \xNN' \
|
||
"(expected $expect; got $actual)"
|
||
;;
|
||
esac
|
||
|
||
# check that hex bytes are protected with square braces if needed
|
||
expect=$'$\'1\\x[11]1\''
|
||
actual=$(printf %q $'1\x[11]1')
|
||
[[ $actual == "$expect" ]] || err_exit 'shell-quoting: hex bytes not protected from subsequent hex-like chars' \
|
||
"(expected $expect; got $actual)"
|
||
|
||
# ======
|
||
# https://github.com/ksh93/ksh/issues/290
|
||
var=dummy
|
||
exp='{}'
|
||
got=$(set +x; eval 'echo ${var:+'\''{}'\''}' 2>&1)
|
||
[[ $got == "$exp" ]] || err_exit "Single quotes misparsed in expansion operator string (1)" \
|
||
"(expected $(printf %q "$exp"), got $(printf %q "$got"))"
|
||
unset var
|
||
exp='}'
|
||
got=$(set +x; eval 'echo ${var:-'\''}'\''}' 2>&1)
|
||
[[ $got == "$exp" ]] || err_exit "Single quotes misparsed in expansion operator string (2)" \
|
||
"(expected $(printf %q "$exp"), got $(printf %q "$got"))"
|
||
exp='x'
|
||
got=$(var=x; set +x; eval 'echo ${var:-'\''{}'\''}' 2>&1)
|
||
[[ $got == "$exp" ]] || err_exit "Single quotes misparsed in expansion operator string (3)" \
|
||
"(expected $(printf %q "$exp"), got $(printf %q "$got"))"
|
||
exp=''
|
||
got=$(var=; set +x; eval 'echo ${var:+'\''{}'\''}' 2>&1)
|
||
[[ $got == "$exp" ]] || err_exit "Single quotes misparsed in expansion operator string (4)" \
|
||
"(expected $(printf %q "$exp"), got $(printf %q "$got"))"
|
||
exp='{}'
|
||
got=$(unset var; set +x; eval 'echo ${var-'\''{}'\''}' 2>&1)
|
||
[[ $got == "$exp" ]] || err_exit "Single quotes misparsed in expansion operator string (5)" \
|
||
"(expected $(printf %q "$exp"), got $(printf %q "$got"))"
|
||
exp=''
|
||
got=$(unset var; set +x; eval 'echo ${var+'\''{}'\''}' 2>&1)
|
||
[[ $got == "$exp" ]] || err_exit "Single quotes misparsed in expansion operator string (6)" \
|
||
"(expected $(printf %q "$exp"), got $(printf %q "$got"))"
|
||
|
||
# ======
|
||
exit $((Errors<125?Errors:125))
|