ash: parser: Fix handling of empty aliases

Upstream commit:

    Date: Tue, 28 Apr 2020 01:15:26 +1000
    parser: Fix handling of empty aliases

    Dash was incorrectly handling empty aliases. When attempting to use an
    empty alias with nothing else, I'm (incorrectly) prompted for more
    input:

    ```
    $ alias empty=''
    $ empty
    >
    ```

    Other shells (e.g., bash, yash) correctly handle the lone, empty alias as an
    empty command:

    ```
    $ alias empty=''
    $ empty
    $
    ```

    The problem here is that we incorrectly enter the loop eating TNLs
    in readtoken().  This patch fixes it by setting checkkwd correctly.

function                                             old     new   delta
list                                                 351     355      +4

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2021-09-08 00:39:16 +02:00
parent 6a9b3f7acf
commit 30af5938af

View File

@ -11755,27 +11755,28 @@ static union node *andor(void);
static union node *pipeline(void);
static union node *parse_command(void);
static void parseheredoc(void);
static int peektoken(void);
static int readtoken(void);
static union node *
list(int nlflag)
{
int chknl = nlflag & 1 ? 0 : CHKNL;
union node *n1, *n2, *n3;
int tok;
n1 = NULL;
for (;;) {
switch (readtoken()) {
checkkwd = chknl | CHKKWD | CHKALIAS;
tok = readtoken();
switch (tok) {
case TNL:
if (!(nlflag & 1))
break;
parseheredoc();
return n1;
case TEOF:
if (!n1 && (nlflag & 1))
if (!n1 && !chknl)
n1 = NODE_EOF;
out_eof:
parseheredoc();
tokpushback++;
lasttoken = TEOF;
@ -11783,8 +11784,7 @@ list(int nlflag)
}
tokpushback++;
checkkwd = CHKNL | CHKKWD | CHKALIAS;
if (nlflag == 2 && ((1 << peektoken()) & tokendlist))
if (nlflag == 2 && ((1 << tok) & tokendlist))
return n1;
nlflag |= 2;
@ -11813,15 +11813,16 @@ list(int nlflag)
n1 = n3;
}
switch (tok) {
case TNL:
case TEOF:
goto out_eof;
case TNL:
tokpushback = 1;
/* fall through */
case TBACKGND:
case TSEMI:
break;
default:
if ((nlflag & 1))
if (!chknl)
raise_error_unexpected_syntax(-1);
tokpushback = 1;
return n1;
@ -11995,8 +11996,9 @@ simplecmd(void)
switch (t) {
#if BASH_FUNCTION
case TFUNCTION:
if (peektoken() != TWORD)
if (readtoken() != TWORD)
raise_error_unexpected_syntax(TWORD);
tokpushback = 1;
function_flag = 1;
break;
#endif
@ -12033,7 +12035,9 @@ simplecmd(void)
#if BASH_FUNCTION
if (function_flag) {
checkkwd = CHKNL | CHKKWD;
switch (peektoken()) {
t = readtoken();
tokpushback = 1;
switch (t) {
case TBEGIN:
case TIF:
case TCASE:
@ -13306,16 +13310,6 @@ readtoken(void)
return t;
}
static int
peektoken(void)
{
int t;
t = readtoken();
tokpushback = 1;
return t;
}
/*
* Read and parse a command. Returns NODE_EOF on end of file.
* (NULL is a valid parse tree indicating a blank line.)