diff options
author | Ron Yorston <rmy@pobox.com> | 2020-01-23 11:26:08 +0000 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2020-01-29 13:59:45 +0100 |
commit | b0c711e64f868fcab0711d8d0f86aaaa4ed93158 (patch) | |
tree | 42a92619ef723cce5153eb0160df8f36cf9dc5c4 /shell | |
parent | eb7f9acda147543079f261753a11d2afa340fc5e (diff) | |
download | busybox-w32-b0c711e64f868fcab0711d8d0f86aaaa4ed93158.tar.gz busybox-w32-b0c711e64f868fcab0711d8d0f86aaaa4ed93158.tar.bz2 busybox-w32-b0c711e64f868fcab0711d8d0f86aaaa4ed93158.zip |
ash: improve expandstr()
The dash maintainer recently posted a fix for issues with expanding
PS1. These had already been fixed differently in BusyBox ash. Borrow
a couple of improvements:
- Use a single call to setjmp() to trap errors in both readtoken1()
and expandarg().
- In case of error set the prompt to the literal value of PS1 rather
than the half-digested nonsense in stackblock() which might include
ugly control characters.
function old new delta
expandstr 353 300 -53
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 | 41 |
1 files changed, 21 insertions, 20 deletions
diff --git a/shell/ash.c b/shell/ash.c index 4b5eafa7c..d6040f47e 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -13098,29 +13098,27 @@ expandstr(const char *ps, int syntax_type) | |||
13098 | volatile int saveint; | 13098 | volatile int saveint; |
13099 | struct jmploc *volatile savehandler = exception_handler; | 13099 | struct jmploc *volatile savehandler = exception_handler; |
13100 | struct jmploc jmploc; | 13100 | struct jmploc jmploc; |
13101 | const char *volatile result; | ||
13102 | int err; | ||
13101 | 13103 | ||
13102 | /* XXX Fix (char *) cast. */ | 13104 | /* XXX Fix (char *) cast. */ |
13103 | setinputstring((char *)ps); | 13105 | setinputstring((char *)ps); |
13104 | 13106 | ||
13105 | saveprompt = doprompt; | 13107 | saveprompt = doprompt; |
13106 | doprompt = 0; | 13108 | doprompt = 0; |
13109 | result = ps; | ||
13110 | |||
13111 | SAVE_INT(saveint); | ||
13112 | err = setjmp(jmploc.loc); | ||
13113 | if (err) | ||
13114 | goto out; | ||
13107 | 13115 | ||
13108 | /* readtoken1() might die horribly. | 13116 | /* readtoken1() might die horribly. |
13109 | * Try a prompt with syntactically wrong command: | 13117 | * Try a prompt with syntactically wrong command: |
13110 | * PS1='$(date "+%H:%M:%S) > ' | 13118 | * PS1='$(date "+%H:%M:%S) > ' |
13111 | */ | 13119 | */ |
13112 | SAVE_INT(saveint); | 13120 | exception_handler = &jmploc; |
13113 | if (setjmp(jmploc.loc) == 0) { | 13121 | readtoken1(pgetc(), syntax_type, FAKEEOFMARK, 0); |
13114 | exception_handler = &jmploc; | ||
13115 | readtoken1(pgetc(), syntax_type, FAKEEOFMARK, 0); | ||
13116 | } | ||
13117 | exception_handler = savehandler; | ||
13118 | RESTORE_INT(saveint); | ||
13119 | |||
13120 | doprompt = saveprompt; | ||
13121 | |||
13122 | /* Try: PS1='`xxx(`' */ | ||
13123 | unwindfiles(file_stop); | ||
13124 | 13122 | ||
13125 | n.narg.type = NARG; | 13123 | n.narg.type = NARG; |
13126 | n.narg.next = NULL; | 13124 | n.narg.next = NULL; |
@@ -13130,17 +13128,20 @@ expandstr(const char *ps, int syntax_type) | |||
13130 | /* expandarg() might fail too: | 13128 | /* expandarg() might fail too: |
13131 | * PS1='$((123+))' | 13129 | * PS1='$((123+))' |
13132 | */ | 13130 | */ |
13133 | SAVE_INT(saveint); | 13131 | expandarg(&n, NULL, EXP_QUOTED); |
13134 | if (setjmp(jmploc.loc) == 0) { | 13132 | result = stackblock(); |
13135 | exception_handler = &jmploc; | 13133 | |
13136 | expandarg(&n, NULL, EXP_QUOTED); | 13134 | out: |
13137 | } else if (exception_type == EXEXIT) { | ||
13138 | exitshell(); | ||
13139 | } | ||
13140 | exception_handler = savehandler; | 13135 | exception_handler = savehandler; |
13136 | if (err && exception_type != EXERROR) | ||
13137 | longjmp(exception_handler->loc, 1); | ||
13141 | RESTORE_INT(saveint); | 13138 | RESTORE_INT(saveint); |
13142 | 13139 | ||
13143 | return stackblock(); | 13140 | doprompt = saveprompt; |
13141 | /* Try: PS1='`xxx(`' */ | ||
13142 | unwindfiles(file_stop); | ||
13143 | |||
13144 | return result; | ||
13144 | } | 13145 | } |
13145 | 13146 | ||
13146 | static inline int | 13147 | static inline int |