[PATCH v3 2/2] ash: catch error in arithmetic expansion in PS1
Ron Yorston
rmy at pobox.com
Thu Apr 18 12:16:08 UTC 2019
Setting PS1 to:
PS1='$((123+))'
causes the shell to enter an infinite error loop:
sh: arithmetic syntax error
Catch any exception raised by expandarg() in expandstr() and allow
processing to continue.
If either readtoken1() or expandarg() fails return an empty string.
function old new delta
expandstr 262 387 +125
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 125/0) Total: 125 bytes
v2: If readtoken1() fails don't try expandarg(). If either fails return
an empty string rather than part-digested nonsense.
v3: Ensure there's space for the empty string on the stack.
Signed-off-by: Ron Yorston <rmy at pobox.com>
---
shell/ash.c | 48 ++++++++++++++++++++++++++++++++++--------------
1 file changed, 34 insertions(+), 14 deletions(-)
diff --git a/shell/ash.c b/shell/ash.c
index 039524010..9bea4cd42 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -13043,6 +13043,10 @@ expandstr(const char *ps, int syntax_type)
union node n;
int saveprompt;
struct parsefile *file_stop = g_parsefile;
+ volatile int saveint;
+ struct jmploc *volatile savehandler = exception_handler;
+ struct jmploc jmploc;
+ int err;
/* XXX Fix (char *) cast. */
setinputstring((char *)ps);
@@ -13054,29 +13058,45 @@ expandstr(const char *ps, int syntax_type)
* Try a prompt with syntactically wrong command:
* PS1='$(date "+%H:%M:%S) > '
*/
- {
- volatile int saveint;
- struct jmploc *volatile savehandler = exception_handler;
- struct jmploc jmploc;
+ SAVE_INT(saveint);
+ err = setjmp(jmploc.loc);
+ if (err == 0) {
+ exception_handler = &jmploc;
+ readtoken1(pgetc(), syntax_type, FAKEEOFMARK, 0);
+ }
+ exception_handler = savehandler;
+ RESTORE_INT(saveint);
+
+ doprompt = saveprompt;
+
+ unwindfiles(file_stop);
+
+ if (err == 0) {
+ n.narg.type = NARG;
+ n.narg.next = NULL;
+ n.narg.text = wordtext;
+ n.narg.backquote = backquotelist;
+
+ /* expandarg() might fail too:
+ * PS1='$((123+))'
+ */
SAVE_INT(saveint);
- if (setjmp(jmploc.loc) == 0) {
+ err = setjmp(jmploc.loc);
+ if (err == 0) {
exception_handler = &jmploc;
- readtoken1(pgetc(), syntax_type, FAKEEOFMARK, 0);
+ expandarg(&n, NULL, EXP_QUOTED);
}
exception_handler = savehandler;
RESTORE_INT(saveint);
}
- doprompt = saveprompt;
+ if (err) {
+ char *out;
- unwindfiles(file_stop);
-
- n.narg.type = NARG;
- n.narg.next = NULL;
- n.narg.text = wordtext;
- n.narg.backquote = backquotelist;
+ STARTSTACKSTR(out);
+ STACKSTRNUL(out);
+ }
- expandarg(&n, NULL, EXP_QUOTED);
return stackblock();
}
--
2.20.1
More information about the busybox
mailing list