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