From 30af5938afad076e12b8ece123cab0b8bc92a596 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 8 Sep 2021 00:39:16 +0200 Subject: [PATCH] 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 --- shell/ash.c | 36 +++++++++++++++--------------------- 1 file 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.)