diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2021-09-08 01:43:12 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2021-09-08 01:43:12 +0200 |
commit | 8c68ae8416c8b54222eb3cd1d4908a570147e134 (patch) | |
tree | 0da34e8659371340b1dfd5984043be00bde96ebb | |
parent | c54025612711a6b1997efd99206b9fbcaa5a29cf (diff) |
ash: parser: Fix alias expansion after heredoc or newlines
Upstream commit:
Date: Wed, 29 Apr 2020 00:19:59 +1000
parser: Fix alias expansion after heredoc or newlines
This script should print OK:
alias a="case x in " b=x
a
b) echo BAD;; esac
alias BEGIN={ END=}
BEGIN
cat <<- EOF > /dev/null
$(:)
EOF
END
: <<- EOF &&
$(:)
EOF
BEGIN
echo OK
END
However, because the value of checkkwd is either zeroed when it
shouldn't, or isn't zeroed when it should, dash currently gets
it wrong in every case.
This patch fixes it by saving checkkwd and zeroing it where needed.
function old new delta
readtoken 157 176 +19
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | shell/ash.c | 7 | ||||
-rw-r--r-- | shell/ash_test/ash-alias/alias_brace.right | 1 | ||||
-rwxr-xr-x | shell/ash_test/ash-alias/alias_brace.tests | 16 | ||||
-rw-r--r-- | shell/ash_test/ash-alias/alias_case.right | 1 | ||||
-rwxr-xr-x | shell/ash_test/ash-alias/alias_case.tests | 8 |
5 files changed, 31 insertions, 2 deletions
diff --git a/shell/ash.c b/shell/ash.c index f1c21188e..5a001b004 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -13265,10 +13265,14 @@ readtoken(void) if (kwd & CHKNL) { while (t == TNL) { parseheredoc(); + checkkwd = 0; t = xxreadtoken(); } } + kwd |= checkkwd; + checkkwd = 0; + if (t != TWORD || quoteflag) { goto out; } @@ -13287,7 +13291,7 @@ readtoken(void) } } - if (checkkwd & CHKALIAS) { + if (kwd & CHKALIAS) { #if ENABLE_ASH_ALIAS struct alias *ap; ap = lookupalias(wordtext, 1); @@ -13300,7 +13304,6 @@ readtoken(void) #endif } out: - checkkwd = 0; #if DEBUG if (!alreadyseen) TRACE(("token '%s' %s\n", tokname_array[t], t == TWORD ? wordtext : "")); diff --git a/shell/ash_test/ash-alias/alias_brace.right b/shell/ash_test/ash-alias/alias_brace.right new file mode 100644 index 000000000..7326d9603 --- /dev/null +++ b/shell/ash_test/ash-alias/alias_brace.right @@ -0,0 +1 @@ +Ok diff --git a/shell/ash_test/ash-alias/alias_brace.tests b/shell/ash_test/ash-alias/alias_brace.tests new file mode 100755 index 000000000..7571b64ac --- /dev/null +++ b/shell/ash_test/ash-alias/alias_brace.tests @@ -0,0 +1,16 @@ +# Note: bash would need: +#shopt -s expand_aliases +# to enable aliases in non-interactive mode +alias BEGIN={ END=} +BEGIN + cat <<- EOF > /dev/null + $(:) + EOF +END + +: <<- EOF && + $(:) +EOF +BEGIN + echo Ok +END diff --git a/shell/ash_test/ash-alias/alias_case.right b/shell/ash_test/ash-alias/alias_case.right new file mode 100644 index 000000000..7326d9603 --- /dev/null +++ b/shell/ash_test/ash-alias/alias_case.right @@ -0,0 +1 @@ +Ok diff --git a/shell/ash_test/ash-alias/alias_case.tests b/shell/ash_test/ash-alias/alias_case.tests new file mode 100755 index 000000000..ed8275875 --- /dev/null +++ b/shell/ash_test/ash-alias/alias_case.tests @@ -0,0 +1,8 @@ +# Note: bash would need: +#shopt -s expand_aliases +# to enable aliases in non-interactive mode +alias a="case x in " b=x +a +b) echo BAD;; +*) echo Ok;; +esac |