diff options
author | Ron Yorston <rmy@pobox.com> | 2015-10-29 11:30:55 +0000 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2015-10-29 21:44:11 +0100 |
commit | c0e007663d30f83b0e5e074db34dcffaa8915e99 (patch) | |
tree | 4fe5fc1aced6973b4e6dfe758cef56127f10b343 | |
parent | 6bd2fabc52fa76b69a65772878e2e745c0fff3ff (diff) | |
download | busybox-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.c | 63 |
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); | |||
10524 | static union node *pipeline(void); | 10524 | static union node *pipeline(void); |
10525 | static union node *parse_command(void); | 10525 | static union node *parse_command(void); |
10526 | static void parseheredoc(void); | 10526 | static void parseheredoc(void); |
10527 | static char peektoken(void); | 10527 | static int peektoken(void); |
10528 | static int readtoken(void); | 10528 | static int readtoken(void); |
10529 | 10529 | ||
10530 | static union node * | 10530 | static 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 | ||
11957 | static char | 11958 | static int |
11958 | peektoken(void) | 11959 | peektoken(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) | |||
11971 | static union node * | 11972 | static union node * |
11972 | parsecmd(int interact) | 11973 | parsecmd(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 | ||