diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2021-09-08 00:39:16 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2021-09-08 00:39:16 +0200 |
commit | 30af5938afad076e12b8ece123cab0b8bc92a596 (patch) | |
tree | 845ac3f69f996ddc91e37cd2f07a34636cdd5bdf | |
parent | 6a9b3f7acfaa7365515f1eb70427d5ddd687c162 (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.c | 36 |
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.) |