From b0c711e64f868fcab0711d8d0f86aaaa4ed93158 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Thu, 23 Jan 2020 11:26:08 +0000 Subject: 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 Signed-off-by: Denys Vlasenko --- shell/ash.c | 41 +++++++++++++++++++++-------------------- 1 file 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) volatile int saveint; struct jmploc *volatile savehandler = exception_handler; struct jmploc jmploc; + const char *volatile result; + int err; /* XXX Fix (char *) cast. */ setinputstring((char *)ps); saveprompt = doprompt; doprompt = 0; + result = ps; + + SAVE_INT(saveint); + err = setjmp(jmploc.loc); + if (err) + goto out; /* readtoken1() might die horribly. * Try a prompt with syntactically wrong command: * PS1='$(date "+%H:%M:%S) > ' */ - SAVE_INT(saveint); - if (setjmp(jmploc.loc) == 0) { - exception_handler = &jmploc; - readtoken1(pgetc(), syntax_type, FAKEEOFMARK, 0); - } - exception_handler = savehandler; - RESTORE_INT(saveint); - - doprompt = saveprompt; - - /* Try: PS1='`xxx(`' */ - unwindfiles(file_stop); + exception_handler = &jmploc; + readtoken1(pgetc(), syntax_type, FAKEEOFMARK, 0); n.narg.type = NARG; n.narg.next = NULL; @@ -13130,17 +13128,20 @@ expandstr(const char *ps, int syntax_type) /* expandarg() might fail too: * PS1='$((123+))' */ - SAVE_INT(saveint); - if (setjmp(jmploc.loc) == 0) { - exception_handler = &jmploc; - expandarg(&n, NULL, EXP_QUOTED); - } else if (exception_type == EXEXIT) { - exitshell(); - } + expandarg(&n, NULL, EXP_QUOTED); + result = stackblock(); + +out: exception_handler = savehandler; + if (err && exception_type != EXERROR) + longjmp(exception_handler->loc, 1); RESTORE_INT(saveint); - return stackblock(); + doprompt = saveprompt; + /* Try: PS1='`xxx(`' */ + unwindfiles(file_stop); + + return result; } static inline int -- cgit v1.2.3