From 8c68ae8416c8b54222eb3cd1d4908a570147e134 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 8 Sep 2021 01:43:12 +0200 Subject: [PATCH] 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 --- shell/ash.c | 7 +++++-- shell/ash_test/ash-alias/alias_brace.right | 1 + shell/ash_test/ash-alias/alias_brace.tests | 16 ++++++++++++++++ shell/ash_test/ash-alias/alias_case.right | 1 + shell/ash_test/ash-alias/alias_case.tests | 8 ++++++++ 5 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 shell/ash_test/ash-alias/alias_brace.right create mode 100755 shell/ash_test/ash-alias/alias_brace.tests create mode 100644 shell/ash_test/ash-alias/alias_case.right create mode 100755 shell/ash_test/ash-alias/alias_case.tests 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