sh: Fix executing wrong command with ${unsetvar#$(cmdsubst)}$(cmdsubst).
The parsed internal representation of words consists of a byte string with a list of nodes (commands in command substitution). Each unescaped CTLBACKQ or CTLBACKQ | CTLQUOTE byte corresponds to an entry in the list. If param in ${param#%##%%word} is not set, the word is not expanded (in a deviation of POSIX shared with other ash variants and ksh93). Erroneously, the pointer in the list of commands (argbackq) was not advanced. This caused the wrong command to be executed later if the outer word contained another command substitution. Example: echo "${unsetvar#$(echo a)}$(echo b)" wrote "a" but should write "b". MFC after: 1 week
This commit is contained in:
parent
ead3ad6b5c
commit
8999a290ab
@ -769,8 +769,10 @@ evalvar(const char *p, int flag, struct worddest *dst)
|
||||
case VSTRIMLEFTMAX:
|
||||
case VSTRIMRIGHT:
|
||||
case VSTRIMRIGHTMAX:
|
||||
if (!set)
|
||||
if (!set) {
|
||||
set = 1;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Terminate the string and start recording the pattern
|
||||
* right after it
|
||||
|
@ -44,6 +44,7 @@ ${PACKAGE}FILES+= cmdsubst19.0
|
||||
${PACKAGE}FILES+= cmdsubst20.0
|
||||
${PACKAGE}FILES+= cmdsubst21.0
|
||||
${PACKAGE}FILES+= cmdsubst22.0
|
||||
${PACKAGE}FILES+= cmdsubst23.0
|
||||
${PACKAGE}FILES+= export1.0
|
||||
${PACKAGE}FILES+= export2.0
|
||||
${PACKAGE}FILES+= export3.0
|
||||
|
5
bin/sh/tests/expansion/cmdsubst23.0
Normal file
5
bin/sh/tests/expansion/cmdsubst23.0
Normal file
@ -0,0 +1,5 @@
|
||||
# $FreeBSD$
|
||||
|
||||
unset n
|
||||
x=abcd
|
||||
[ "X${n#$(echo a)}X${x#$(echo ab)}X$(echo abc)X" = XXcdXabcX ]
|
Loading…
Reference in New Issue
Block a user