diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2021-09-08 00:56:53 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2021-09-08 00:56:53 +0200 |
commit | 1c06ddd8bbbd6906e5bf00ec93e04d5090718be9 (patch) | |
tree | 92aaf06801f38754d41e039038d538959cefb866 | |
parent | 30af5938afad076e12b8ece123cab0b8bc92a596 (diff) | |
download | busybox-w32-1c06ddd8bbbd6906e5bf00ec93e04d5090718be9.tar.gz busybox-w32-1c06ddd8bbbd6906e5bf00ec93e04d5090718be9.tar.bz2 busybox-w32-1c06ddd8bbbd6906e5bf00ec93e04d5090718be9.zip |
ash: parser: Save and restore heredoclist in expandstr
Upstream commit:
Date: Sun, 17 May 2020 23:36:25 +1000
parser: Save and restore heredoclist in expandstr
On Sun, May 17, 2020 at 01:19:28PM +0100, Harald van Dijk wrote:
> This still does not restore the state completely. It does not clean up any
> pending heredocs. I see:
>
> $ PS1='$(<<EOF "'
> src/dash: 1: Syntax error: Unterminated quoted string
> $(<<EOF ":
> >
>
> That is, after entering the ':' command, the shell is still trying to read
> the heredoc from the prompt.
This patch saves and restores the heredoclist in expandstr.
It also removes a bunch of unnecessary volatiles as those variables
are only referenced in case of a longjmp other than one started by
a signal like SIGINT.
function old new delta
expandstr 268 255 -13
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | shell/ash.c | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/shell/ash.c b/shell/ash.c index 5a18ff1a1..cf62fdf75 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -13359,23 +13359,26 @@ parseheredoc(void) | |||
13359 | static const char * | 13359 | static const char * |
13360 | expandstr(const char *ps, int syntax_type) | 13360 | expandstr(const char *ps, int syntax_type) |
13361 | { | 13361 | { |
13362 | union node n; | 13362 | struct parsefile *file_stop; |
13363 | struct jmploc *volatile savehandler; | ||
13364 | struct heredoc *saveheredoclist; | ||
13365 | const char *result; | ||
13363 | int saveprompt; | 13366 | int saveprompt; |
13364 | struct parsefile *file_stop = g_parsefile; | ||
13365 | volatile int saveint; | ||
13366 | struct jmploc *volatile savehandler = exception_handler; | ||
13367 | struct jmploc jmploc; | 13367 | struct jmploc jmploc; |
13368 | const char *volatile result; | 13368 | union node n; |
13369 | int err; | 13369 | int err; |
13370 | 13370 | ||
13371 | file_stop = g_parsefile; | ||
13372 | |||
13371 | /* XXX Fix (char *) cast. */ | 13373 | /* XXX Fix (char *) cast. */ |
13372 | setinputstring((char *)ps); | 13374 | setinputstring((char *)ps); |
13373 | 13375 | ||
13376 | saveheredoclist = heredoclist; | ||
13377 | heredoclist = NULL; | ||
13374 | saveprompt = doprompt; | 13378 | saveprompt = doprompt; |
13375 | doprompt = 0; | 13379 | doprompt = 0; |
13376 | result = ps; | 13380 | result = ps; |
13377 | 13381 | savehandler = exception_handler; | |
13378 | SAVE_INT(saveint); | ||
13379 | err = setjmp(jmploc.loc); | 13382 | err = setjmp(jmploc.loc); |
13380 | if (err) | 13383 | if (err) |
13381 | goto out; | 13384 | goto out; |
@@ -13402,11 +13405,11 @@ out: | |||
13402 | exception_handler = savehandler; | 13405 | exception_handler = savehandler; |
13403 | if (err && exception_type != EXERROR) | 13406 | if (err && exception_type != EXERROR) |
13404 | longjmp(exception_handler->loc, 1); | 13407 | longjmp(exception_handler->loc, 1); |
13405 | RESTORE_INT(saveint); | ||
13406 | 13408 | ||
13407 | doprompt = saveprompt; | 13409 | doprompt = saveprompt; |
13408 | /* Try: PS1='`xxx(`' */ | 13410 | /* Try: PS1='`xxx(`' */ |
13409 | unwindfiles(file_stop); | 13411 | unwindfiles(file_stop); |
13412 | heredoclist = saveheredoclist; | ||
13410 | 13413 | ||
13411 | return result; | 13414 | return result; |
13412 | } | 13415 | } |