From 8999a290abaeccdeb56ca9032cf07fa898e3a342 Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Fri, 10 Mar 2017 16:04:00 +0000 Subject: [PATCH] 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 --- bin/sh/expand.c | 4 +++- bin/sh/tests/expansion/Makefile | 1 + bin/sh/tests/expansion/cmdsubst23.0 | 5 +++++ 3 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 bin/sh/tests/expansion/cmdsubst23.0 diff --git a/bin/sh/expand.c b/bin/sh/expand.c index 832b51f12f53..1b8a75e70503 100644 --- a/bin/sh/expand.c +++ b/bin/sh/expand.c @@ -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 diff --git a/bin/sh/tests/expansion/Makefile b/bin/sh/tests/expansion/Makefile index c0622323517b..99ed07fc719f 100644 --- a/bin/sh/tests/expansion/Makefile +++ b/bin/sh/tests/expansion/Makefile @@ -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 diff --git a/bin/sh/tests/expansion/cmdsubst23.0 b/bin/sh/tests/expansion/cmdsubst23.0 new file mode 100644 index 000000000000..cde86981f461 --- /dev/null +++ b/bin/sh/tests/expansion/cmdsubst23.0 @@ -0,0 +1,5 @@ +# $FreeBSD$ + +unset n +x=abcd +[ "X${n#$(echo a)}X${x#$(echo ab)}X$(echo abc)X" = XXcdXabcX ]