[git commit] ash: improve expandstr()

Denys Vlasenko vda.linux at googlemail.com
Wed Jan 29 12:59:45 UTC 2020


commit: https://git.busybox.net/busybox/commit/?id=b0c711e64f868fcab0711d8d0f86aaaa4ed93158
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

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 at pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 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


More information about the busybox-cvs mailing list