diff mbox series

parser: Catch errors in expandstr

Message ID 20200121063959.tel7ty76fkz33xpn@gondor.apana.org.au (mailing list archive)
State Superseded
Delegated to: Herbert Xu
Headers show
Series parser: Catch errors in expandstr | expand

Commit Message

Herbert Xu Jan. 21, 2020, 6:39 a.m. UTC
On Fri, Dec 13, 2019 at 02:51:34PM +0000, Simon Ser wrote:
> Just noticed another dash bug: when setting invalid PS1 values dash
> enters an infinite loop.
> 
> For instance, setting PS1='$(' makes dash print many of these:
> 
>    dash: 1: Syntax error: end of file unexpected (expecting ")")
> 
> It would be nice to fallback to the default PS1 value on error.

This patch fixes it by using the literal value of PS1 should an
error occur during expansion.

Reported-by: Simon Ser <contact@emersion.fr>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Comments

Simon Ser Jan. 21, 2020, 5:06 p.m. UTC | #1
On Tuesday, January 21, 2020 7:39 AM, Herbert Xu <herbert@gondor.apana.org.au> wrote:

> On Fri, Dec 13, 2019 at 02:51:34PM +0000, Simon Ser wrote:
>
> > Just noticed another dash bug: when setting invalid PS1 values dash
> > enters an infinite loop.
> > For instance, setting PS1='$(' makes dash print many of these:
> > dash: 1: Syntax error: end of file unexpected (expecting ")")
> > It would be nice to fallback to the default PS1 value on error.
>
> This patch fixes it by using the literal value of PS1 should an
> error occur during expansion.
>
> Reported-by: Simon Ser <contact@emersion.fr>
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Thanks, works!

Tested-by: Simon Ser <contact@emersion.fr>
Ron Yorston Feb. 26, 2020, 9:12 p.m. UTC | #2
Herbert Xu wrote:
>This patch fixes it by using the literal value of PS1 should an
>error occur during expansion.

There's another case that should be handled.  PS1='`xxx(`' causes the
shell to exit because the old-style backquote leaves an additional file
on the stack.

Signed-off-by: Ron Yorston <rmy@pobox.com>
---
 src/parser.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/parser.c b/src/parser.c
index 201d5bd..d7e717a 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -1572,12 +1572,14 @@ const char *
 expandstr(const char *ps)
 {
 	struct jmploc *volatile savehandler;
+	struct parsefile *file_stop;
 	const char *volatile result;
 	volatile int saveprompt;
 	struct jmploc jmploc;
 	union node n;
 	int err;
 
+	file_stop = parsefile;
 	/* XXX Fix (char *) cast. */
 	setinputstring((char *)ps);
 
@@ -1605,7 +1607,7 @@ out:
 		longjmp(handler->loc, 1);
 
 	doprompt = saveprompt;
-	popfile();
+	unwindfiles(file_stop);
 
 	return result;
 }
Herbert Xu Feb. 28, 2020, 12:40 a.m. UTC | #3
On Wed, Feb 26, 2020 at 09:12:04PM +0000, Ron Yorston wrote:
> Herbert Xu wrote:
> >This patch fixes it by using the literal value of PS1 should an
> >error occur during expansion.
> 
> There's another case that should be handled.  PS1='`xxx(`' causes the
> shell to exit because the old-style backquote leaves an additional file
> on the stack.
> 
> Signed-off-by: Ron Yorston <rmy@pobox.com>
> ---
>  src/parser.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)

When you send a patch to an existing thread could you please change
the Subject line? Otherwise your patch will be silently dropped by
patchwork.

Thanks,
diff mbox series

Patch

diff --git a/src/parser.c b/src/parser.c
index b318b08..201d5bd 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -1571,28 +1571,43 @@  setprompt(int which)
 const char *
 expandstr(const char *ps)
 {
+	struct jmploc *volatile savehandler;
+	const char *volatile result;
+	volatile int saveprompt;
+	struct jmploc jmploc;
 	union node n;
-	int saveprompt;
+	int err;
 
 	/* XXX Fix (char *) cast. */
 	setinputstring((char *)ps);
 
 	saveprompt = doprompt;
 	doprompt = 0;
+	result = ps;
+	savehandler = handler;
+	if (unlikely(err = setjmp(jmploc.loc)))
+		goto out;
+	handler = &jmploc;
 
 	readtoken1(pgetc_eatbnl(), DQSYNTAX, FAKEEOFMARK, 0);
 
-	doprompt = saveprompt;
-
-	popfile();
-
 	n.narg.type = NARG;
 	n.narg.next = NULL;
 	n.narg.text = wordtext;
 	n.narg.backquote = backquotelist;
 
 	expandarg(&n, NULL, EXP_QUOTED);
-	return stackblock();
+	result = stackblock();
+
+out:
+	handler = savehandler;
+	if (err && exception != EXERROR)
+		longjmp(handler->loc, 1);
+
+	doprompt = saveprompt;
+	popfile();
+
+	return result;
 }
 
 /*