diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2020-04-28 16:17:58 +1000 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2020-05-15 16:24:37 +1000 |
commit | 50fc8edbe2532b573f2edb727861e3649b9dafef (patch) | |
tree | 80f81a8976bc307ec7f57ef3b5e5e5a9b5436ba0 /src | |
parent | parser: Fix handling of empty aliases (diff) | |
download | dash-50fc8edbe2532b573f2edb727861e3649b9dafef.tar.gz dash-50fc8edbe2532b573f2edb727861e3649b9dafef.zip |
parser: Catch errors in expandstr
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. On Wed, Feb 26, 2020 at 09:12:04PM +0000, Ron Yorston wrote: > > 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. Ron's change has been folded into this patch. Reported-by: Simon Ser <contact@emersion.fr> Reported-by: Ron Yorston <rmy@pobox.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'src')
-rw-r--r-- | src/parser.c | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/src/parser.c b/src/parser.c index 5c9e9a0..9c9a7dc 100644 --- a/src/parser.c +++ b/src/parser.c @@ -1562,28 +1562,46 @@ setprompt(int which) const char * expandstr(const char *ps) { + struct parsefile *volatile file_stop; + struct jmploc *volatile savehandler; + const char *volatile result; + volatile int saveprompt; + struct jmploc jmploc; union node n; - int saveprompt; + int err; + + file_stop = parsefile; /* 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; + unwindfiles(file_stop); + + return result; } /* |