summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2021-09-08 00:39:16 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2021-09-08 00:39:16 +0200
commit30af5938afad076e12b8ece123cab0b8bc92a596 (patch)
tree845ac3f69f996ddc91e37cd2f07a34636cdd5bdf
parent6a9b3f7acfaa7365515f1eb70427d5ddd687c162 (diff)
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>
-rw-r--r--shell/ash.c36
1 files changed, 15 insertions, 21 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 35dbb2f28..5a18ff1a1 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -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.)