From 85b00bb0f7c60b9f4da5261633221cc200a0ab7f Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Wed, 17 Aug 2011 20:26:05 +0000 Subject: 29703: crash when failing to parse process substitutions --- ChangeLog | 4 +++- Src/exec.c | 10 +++++++++- Src/subst.c | 2 ++ Test/D03procsubst.ztst | 4 ++++ 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 76eb0d1dc..fa352b0e2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2011-08-17 Peter Stephenson + * 29703: Src/exec.c, Src/subst.c, Test/D03procsubst.ztst: + * users/16253, users/16255: Src/utils.c, Test/D04parameter.ztst: A nulstring should be split like an empty string. @@ -15297,5 +15299,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5438 $ +* $Revision: 1.5439 $ ***************************************************** diff --git a/Src/exec.c b/Src/exec.c index a9164bc64..3c51a3d42 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -3755,7 +3755,15 @@ parsecmd(char *cmd, char **eptr) for (str = cmd + 2; *str && *str != Outpar; str++); if (!*str || cmd[1] != Inpar) { - zerr("oops."); + /* + * This can happen if the expression is being parsed + * inside another construct, e.g. as a value within ${..:..} etc. + * So print a proper error message instead of the not very + * useful but traditional "oops". + */ + char *errstr = dupstrpfx(cmd, 2); + untokenize(errstr); + zerr("unterminated `%s...)'", errstr); return NULL; } *str = '\0'; diff --git a/Src/subst.c b/Src/subst.c index 1b0097001..66e0bbe77 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -162,6 +162,8 @@ stringsubst(LinkList list, LinkNode node, int ssub, int asssub) subst = getproc(str, &rest); /* <(...) or >(...) */ else subst = getoutputfile(str, &rest); /* =(...) */ + if (errflag) + return NULL; if (!subst) subst = ""; diff --git a/Test/D03procsubst.ztst b/Test/D03procsubst.ztst index 37a67630f..602b1da15 100644 --- a/Test/D03procsubst.ztst +++ b/Test/D03procsubst.ztst @@ -84,3 +84,7 @@ ) 0:=(...) preceded by other stuff has no special effect >everything,=(here is left),alone + + print something=${:-=(echo 'C,D),(F,G)'} +1: Graceful handling of bad substitution in enclosed context +?(eval):1: unterminated `=(...)' -- cgit 1.4.1