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 |
