about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--Src/exec.c7
-rw-r--r--Src/parse.c12
-rw-r--r--Src/subst.c1
4 files changed, 28 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index e61cc364b..9d331ae19 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2008-09-01  Peter Stephenson  <p.w.stephenson@ntlworld.com>
+
+	* 25587: Src/exec.c, Src/parse.c, Src/subst.c: foo==(stuff)
+	was mishandled owing to parse errors; mishandling it caused
+	a crash because of lack of care on failure of process
+	substitution; assignments that went through execcmd() failed
+	to set the status.
+
 2008-09-01  Clint Adams  <clint@zsh.org>
 
 	* 25585: Completion/Unix/Command/_git: fix git command completion
diff --git a/Src/exec.c b/Src/exec.c
index 06f08ffb8..cf0efed19 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -2220,6 +2220,7 @@ execcmd(Estate state, int input, int output, int how, int last1)
     doneps4 = 0;
     redir = (wc_code(*state->pc) == WC_REDIR ? ecgetredirs(state) : NULL);
     if (wc_code(*state->pc) == WC_ASSIGN) {
+	cmdoutval = 0;
 	varspc = state->pc;
 	while (wc_code((code = *state->pc)) == WC_ASSIGN)
 	    state->pc += (WC_ASSIGN_TYPE(code) == WC_ASSIGN_SCALAR ?
@@ -2236,6 +2237,12 @@ execcmd(Estate state, int input, int output, int how, int last1)
      * they don't modify their argument strings. */
     args = (type == WC_SIMPLE ?
 	    ecgetlist(state, WC_SIMPLE_ARGC(code), EC_DUP, &htok) : NULL);
+    /*
+     * If assignment but no command get the status from variable
+     * assignment.
+     */
+    if (!args && varspc)
+	lastval = errflag ? errflag : cmdoutval;
 
     for (i = 0; i < 10; i++) {
 	save[i] = -2;
diff --git a/Src/parse.c b/Src/parse.c
index 295b4922f..0812f9137 100644
--- a/Src/parse.c
+++ b/Src/parse.c
@@ -1567,6 +1567,18 @@ par_simple(int *complex, int nr)
 		str = p + 1;
 	    } else
 		equalsplit(tokstr, &str);
+	    for (p = str; *p; p++) {
+		/*
+		 * We can't treat this as "simple" if it contains
+		 * expansions that require process subsitution, since then
+		 * we need process handling.
+		 */
+		if (p[1] == Inpar &&
+		    (*p == Equals || *p == Inang || *p == Outang)) {
+		    *complex = 1;
+		    break;
+		}
+	    }
 	    ecstr(name);
 	    ecstr(str);
 	    isnull = 0;
diff --git a/Src/subst.c b/Src/subst.c
index 7906f80bd..6c3487e9a 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -66,6 +66,7 @@ prefork(LinkList list, int flags)
 	    else
 		setdata(node, (void *) getoutputfile(str));	/* =(...) */
 	    if (!getdata(node)) {
+		setdata(node, dupstring(""));
 		unqueue_signals();
 		return;
 	    }