Message ID | 20200428061758.GA1771@gondor.apana.org.au (mailing list archive) |
---|---|
State | Accepted |
Delegated to: | Herbert Xu |
Headers | show |
Series | [v2] parser: Catch errors in expandstr | expand |
On 28/04/2020 07:17, Herbert Xu wrote: > ---8<--- > 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. This still does not restore the state completely. It does not clean up any pending heredocs. I see: $ PS1='$(<<EOF "' src/dash: 1: Syntax error: Unterminated quoted string $(<<EOF ": > That is, after entering the ':' command, the shell is still trying to read the heredoc from the prompt. I have not looked in detail to see if anything else is not getting cleaned up that should be. Cheers, Harald van Dijk
diff --git a/src/parser.c b/src/parser.c index b318b08..5e36929 100644 --- a/src/parser.c +++ b/src/parser.c @@ -1571,28 +1571,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; } /*