1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-03-09 15:50:02 +00:00

This fixes erroneous syntax errors in parameter expansions such as

${var:-wor)d} or ${var+w(ord}. The parentheses now correctly lose
their normal grammatical meaning within the braces. Fix by Eric
Scrivner (@etscrivner) from July 2018 backported from ksh2020.

This fix complies with POSIX:
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02

src/cmd/ksh93/sh/lex.c: sh_lex():
- Set the ST_QUOTE state when analysing a modifier with parameter
  expansions using operators ':', '-', '+', '='. This state causes
  subsequent characters (including parentheses) to be considered
  quoted, suppressing their normal grammatical meaning.

src/cmd/ksh93/sh/macro.c: varsub():
- Same for skipping the expansion.

Fixes: https://github.com/ksh93/ksh/issues/126
Prior discussion: https://github.com/att/ast/issues/475
This commit is contained in:
Martijn Dekker 2020-09-05 16:20:22 +02:00
parent b3d37b00b0
commit 5ed9ffd6c4
5 changed files with 48 additions and 2 deletions

View file

@ -1040,5 +1040,39 @@ wait
# ${.sh.pid} should be the same as $$ in the parent shell
[[ $$ == ${.sh.pid} ]] || err_exit "\${.sh.pid} and \$$ differ in the parent shell (expected $$, got ${.sh.pid})"
# ======
# Parentheses after the '-', '+', and '=' expansion operators were causing syntax errors.
# Check both the unset variable case and the set variable case for each set of symbols.
unset -v foo
for op in - :- = :=
do for word in '(word)' 'w(or)d' '(wor)d' 'w(ord)' 'w(ord' 'wor)d'
do exp=$(set +x; eval "echo \${foo${op}${word}}" 2>&1)
if [[ $exp != "$word" ]]
then err_exit "\${foo${op}${word}} when foo is not set: expected \"$word\", got \"$exp\""
fi
done
done
foo=some_value
for op in - :- = :=
do for word in '(word)' 'w(or)d' '(wor)d' 'w(ord)' 'w(ord' 'wor)d'
do exp=$(set +x; eval "echo \${foo${op}${word}}" 2>&1)
if [[ $exp != "$foo" ]]
then err_exit "\${foo${op}${word}} when foo is set: expected \"$foo\", got \"$exp\""
fi
done
done
unset -v foo
for op in + :+
do for word in '(word)' 'w(or)d' '(wor)d' 'w(ord)' 'w(ord' 'wor)d'
do exp=$(set +x; eval "echo \${foo${op}${word}}" 2>&1)
if [[ $exp != "" ]]
then err_exit "\${foo${op}${word}} when foo is not set: expected null, got \"$exp\""
fi
done
done
# ======
exit $((Errors<125?Errors:125))