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>
This commit is contained in:
Denys Vlasenko 2021-09-08 01:43:12 +02:00
parent c540256127
commit 8c68ae8416
5 changed files with 31 additions and 2 deletions

View File

@ -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 : ""));

View File

@ -0,0 +1 @@
Ok

View File

@ -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

View File

@ -0,0 +1 @@
Ok

View File

@ -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