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 /shell | |
| 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>
Diffstat (limited to 'shell')
| -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 | ||
