aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2015-10-29 11:30:55 +0000
committerDenys Vlasenko <vda.linux@googlemail.com>2015-10-29 21:44:11 +0100
commitc0e007663d30f83b0e5e074db34dcffaa8915e99 (patch)
tree4fe5fc1aced6973b4e6dfe758cef56127f10b343
parent6bd2fabc52fa76b69a65772878e2e745c0fff3ff (diff)
downloadbusybox-w32-c0e007663d30f83b0e5e074db34dcffaa8915e99.tar.gz
busybox-w32-c0e007663d30f83b0e5e074db34dcffaa8915e99.tar.bz2
busybox-w32-c0e007663d30f83b0e5e074db34dcffaa8915e99.zip
ash: simplify EOF/newline handling in list parser
Processing of here documents in ash has had a couple of breakages which are now the subject of tests. This commit should fix both. It is based on the following commit in dash git by Herbert Xu: <7c245aa> [PARSER] Simplify EOF/newline handling in list parser (See git://git.kernel.org/pub/scm/utils/dash/dash.git) Reported-by: Natanael Copa <ncopa@alpinelinux.org> Signed-off-by: Ron Yorston <rmy@pobox.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--shell/ash.c63
1 files changed, 29 insertions, 34 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 72fc7d524..9a8bab5ab 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -10524,7 +10524,7 @@ static union node *andor(void);
10524static union node *pipeline(void); 10524static union node *pipeline(void);
10525static union node *parse_command(void); 10525static union node *parse_command(void);
10526static void parseheredoc(void); 10526static void parseheredoc(void);
10527static char peektoken(void); 10527static int peektoken(void);
10528static int readtoken(void); 10528static int readtoken(void);
10529 10529
10530static union node * 10530static union node *
@@ -10533,11 +10533,27 @@ list(int nlflag)
10533 union node *n1, *n2, *n3; 10533 union node *n1, *n2, *n3;
10534 int tok; 10534 int tok;
10535 10535
10536 checkkwd = CHKNL | CHKKWD | CHKALIAS;
10537 if (nlflag == 2 && peektoken())
10538 return NULL;
10539 n1 = NULL; 10536 n1 = NULL;
10540 for (;;) { 10537 for (;;) {
10538 switch (peektoken()) {
10539 case TNL:
10540 if (!(nlflag & 1))
10541 break;
10542 parseheredoc();
10543 return n1;
10544
10545 case TEOF:
10546 if (!n1 && (nlflag & 1))
10547 n1 = NODE_EOF;
10548 parseheredoc();
10549 return n1;
10550 }
10551
10552 checkkwd = CHKNL | CHKKWD | CHKALIAS;
10553 if (nlflag == 2 && tokname_array[peektoken()][0])
10554 return n1;
10555 nlflag |= 2;
10556
10541 n2 = andor(); 10557 n2 = andor();
10542 tok = readtoken(); 10558 tok = readtoken();
10543 if (tok == TBACKGND) { 10559 if (tok == TBACKGND) {
@@ -10563,30 +10579,15 @@ list(int nlflag)
10563 n1 = n3; 10579 n1 = n3;
10564 } 10580 }
10565 switch (tok) { 10581 switch (tok) {
10582 case TNL:
10583 case TEOF:
10584 tokpushback = 1;
10585 /* fall through */
10566 case TBACKGND: 10586 case TBACKGND:
10567 case TSEMI: 10587 case TSEMI:
10568 tok = readtoken();
10569 /* fall through */
10570 case TNL:
10571 if (tok == TNL) {
10572 parseheredoc();
10573 if (nlflag == 1)
10574 return n1;
10575 } else {
10576 tokpushback = 1;
10577 }
10578 checkkwd = CHKNL | CHKKWD | CHKALIAS;
10579 if (peektoken())
10580 return n1;
10581 break; 10588 break;
10582 case TEOF:
10583 if (heredoclist)
10584 parseheredoc();
10585 else
10586 pungetc(); /* push back EOF on input */
10587 return n1;
10588 default: 10589 default:
10589 if (nlflag == 1) 10590 if ((nlflag & 1))
10590 raise_error_unexpected_syntax(-1); 10591 raise_error_unexpected_syntax(-1);
10591 tokpushback = 1; 10592 tokpushback = 1;
10592 return n1; 10593 return n1;
@@ -11954,14 +11955,14 @@ readtoken(void)
11954 return t; 11955 return t;
11955} 11956}
11956 11957
11957static char 11958static int
11958peektoken(void) 11959peektoken(void)
11959{ 11960{
11960 int t; 11961 int t;
11961 11962
11962 t = readtoken(); 11963 t = readtoken();
11963 tokpushback = 1; 11964 tokpushback = 1;
11964 return tokname_array[t][0]; 11965 return t;
11965} 11966}
11966 11967
11967/* 11968/*
@@ -11971,18 +11972,12 @@ peektoken(void)
11971static union node * 11972static union node *
11972parsecmd(int interact) 11973parsecmd(int interact)
11973{ 11974{
11974 int t;
11975
11976 tokpushback = 0; 11975 tokpushback = 0;
11976 checkkwd = 0;
11977 heredoclist = 0;
11977 doprompt = interact; 11978 doprompt = interact;
11978 setprompt_if(doprompt, doprompt); 11979 setprompt_if(doprompt, doprompt);
11979 needprompt = 0; 11980 needprompt = 0;
11980 t = readtoken();
11981 if (t == TEOF)
11982 return NODE_EOF;
11983 if (t == TNL)
11984 return NULL;
11985 tokpushback = 1;
11986 return list(1); 11981 return list(1);
11987} 11982}
11988 11983