aboutsummaryrefslogtreecommitdiff
path: root/shell
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 /shell
parent6a9b3f7acfaa7365515f1eb70427d5ddd687c162 (diff)
downloadbusybox-w32-30af5938afad076e12b8ece123cab0b8bc92a596.tar.gz
busybox-w32-30af5938afad076e12b8ece123cab0b8bc92a596.tar.bz2
busybox-w32-30af5938afad076e12b8ece123cab0b8bc92a596.zip
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>
Diffstat (limited to 'shell')
-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);
11755static union node *pipeline(void); 11755static union node *pipeline(void);
11756static union node *parse_command(void); 11756static union node *parse_command(void);
11757static void parseheredoc(void); 11757static void parseheredoc(void);
11758static int peektoken(void);
11759static int readtoken(void); 11758static int readtoken(void);
11760 11759
11761static union node * 11760static union node *
11762list(int nlflag) 11761list(int nlflag)
11763{ 11762{
11763 int chknl = nlflag & 1 ? 0 : CHKNL;
11764 union node *n1, *n2, *n3; 11764 union node *n1, *n2, *n3;
11765 int tok; 11765 int tok;
11766 11766
11767 n1 = NULL; 11767 n1 = NULL;
11768 for (;;) { 11768 for (;;) {
11769 switch (readtoken()) { 11769 checkkwd = chknl | CHKKWD | CHKALIAS;
11770 tok = readtoken();
11771 switch (tok) {
11770 case TNL: 11772 case TNL:
11771 if (!(nlflag & 1))
11772 break;
11773 parseheredoc(); 11773 parseheredoc();
11774 return n1; 11774 return n1;
11775 11775
11776 case TEOF: 11776 case TEOF:
11777 if (!n1 && (nlflag & 1)) 11777 if (!n1 && !chknl)
11778 n1 = NODE_EOF; 11778 n1 = NODE_EOF;
11779 out_eof:
11779 parseheredoc(); 11780 parseheredoc();
11780 tokpushback++; 11781 tokpushback++;
11781 lasttoken = TEOF; 11782 lasttoken = TEOF;
@@ -11783,8 +11784,7 @@ list(int nlflag)
11783 } 11784 }
11784 11785
11785 tokpushback++; 11786 tokpushback++;
11786 checkkwd = CHKNL | CHKKWD | CHKALIAS; 11787 if (nlflag == 2 && ((1 << tok) & tokendlist))
11787 if (nlflag == 2 && ((1 << peektoken()) & tokendlist))
11788 return n1; 11788 return n1;
11789 nlflag |= 2; 11789 nlflag |= 2;
11790 11790
@@ -11813,15 +11813,16 @@ list(int nlflag)
11813 n1 = n3; 11813 n1 = n3;
11814 } 11814 }
11815 switch (tok) { 11815 switch (tok) {
11816 case TNL:
11817 case TEOF: 11816 case TEOF:
11817 goto out_eof;
11818 case TNL:
11818 tokpushback = 1; 11819 tokpushback = 1;
11819 /* fall through */ 11820 /* fall through */
11820 case TBACKGND: 11821 case TBACKGND:
11821 case TSEMI: 11822 case TSEMI:
11822 break; 11823 break;
11823 default: 11824 default:
11824 if ((nlflag & 1)) 11825 if (!chknl)
11825 raise_error_unexpected_syntax(-1); 11826 raise_error_unexpected_syntax(-1);
11826 tokpushback = 1; 11827 tokpushback = 1;
11827 return n1; 11828 return n1;
@@ -11995,8 +11996,9 @@ simplecmd(void)
11995 switch (t) { 11996 switch (t) {
11996#if BASH_FUNCTION 11997#if BASH_FUNCTION
11997 case TFUNCTION: 11998 case TFUNCTION:
11998 if (peektoken() != TWORD) 11999 if (readtoken() != TWORD)
11999 raise_error_unexpected_syntax(TWORD); 12000 raise_error_unexpected_syntax(TWORD);
12001 tokpushback = 1;
12000 function_flag = 1; 12002 function_flag = 1;
12001 break; 12003 break;
12002#endif 12004#endif
@@ -12033,7 +12035,9 @@ simplecmd(void)
12033#if BASH_FUNCTION 12035#if BASH_FUNCTION
12034 if (function_flag) { 12036 if (function_flag) {
12035 checkkwd = CHKNL | CHKKWD; 12037 checkkwd = CHKNL | CHKKWD;
12036 switch (peektoken()) { 12038 t = readtoken();
12039 tokpushback = 1;
12040 switch (t) {
12037 case TBEGIN: 12041 case TBEGIN:
12038 case TIF: 12042 case TIF:
12039 case TCASE: 12043 case TCASE:
@@ -13306,16 +13310,6 @@ readtoken(void)
13306 return t; 13310 return t;
13307} 13311}
13308 13312
13309static int
13310peektoken(void)
13311{
13312 int t;
13313
13314 t = readtoken();
13315 tokpushback = 1;
13316 return t;
13317}
13318
13319/* 13313/*
13320 * Read and parse a command. Returns NODE_EOF on end of file. 13314 * Read and parse a command. Returns NODE_EOF on end of file.
13321 * (NULL is a valid parse tree indicating a blank line.) 13315 * (NULL is a valid parse tree indicating a blank line.)