about summary refs log tree commit diff
path: root/Src/subst.c
diff options
context:
space:
mode:
authorPeter Stephenson <pws@zsh.org>2017-10-13 18:17:09 +0100
committerPeter Stephenson <pws@zsh.org>2017-10-13 18:17:09 +0100
commitb3fa5c528c79b27986a77c92a48b7f70e7f9e7d3 (patch)
treea7aba1e9bf6b5549111a388a9835db091faf9122 /Src/subst.c
parent57cfa8b160d16a37fcd6a5da7c8bcd492c76021e (diff)
downloadzsh-b3fa5c528c79b27986a77c92a48b7f70e7f9e7d3.tar.gz
zsh-b3fa5c528c79b27986a77c92a48b7f70e7f9e7d3.tar.xz
zsh-b3fa5c528c79b27986a77c92a48b7f70e7f9e7d3.zip
41877: Separate out SH_FILE_EXPANSION loop from parameter substitution.
Parameter substitution can add nodes that need to be rescanned by
it, but not by file expansion, so the two don't play well together.
Diffstat (limited to 'Src/subst.c')
-rw-r--r--Src/subst.c39
1 files changed, 23 insertions, 16 deletions
diff --git a/Src/subst.c b/Src/subst.c
index 8c290cccf..d027e3d83 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -108,7 +108,6 @@ prefork(LinkList list, int flags, int *ret_flags)
     queue_signals();
     node = firstnode(list);
     while (node) {
-	LinkNode nextnode = 0;
 	if ((flags & (PREFORK_SINGLE|PREFORK_ASSIGN)) == PREFORK_ASSIGN &&
 	    (insnode = keyvalpairelement(list, node))) {
 	    node = insnode;
@@ -137,23 +136,31 @@ prefork(LinkList list, int flags, int *ret_flags)
 	     * testing if cptr changed...
 	     */
 	    setdata(node, cptr);
-	    /*
-	     * Advance now because we must not expand filenames again
-	     * after string substitution (which may insert new nodes).
-	     */
-	    nextnode = node;
-	    incnode(nextnode);
-	}
-	if (!(node = stringsubst(list, node,
-				 flags & ~(PREFORK_TYPESET|PREFORK_ASSIGN),
-				 ret_flags, asssub))) {
-	    unqueue_signals();
-	    return;
 	}
-	if (isset(SHFILEEXPANSION))
-	    node = nextnode;
 	else
-	    incnode(node);
+	{
+	    if (!(node = stringsubst(list, node,
+				     flags & ~(PREFORK_TYPESET|PREFORK_ASSIGN),
+				     ret_flags, asssub))) {
+		unqueue_signals();
+		return;
+	    }
+	}
+	incnode(node);
+    }
+    if (isset(SHFILEEXPANSION)) {
+	/*
+	 * stringsubst() may insert new nodes, so doesn't work
+	 * well in the same loop as file expansion.
+	 */
+	for (node = firstnode(list); node; incnode(node)) {
+	    if (!(node = stringsubst(list, node,
+				     flags & ~(PREFORK_TYPESET|PREFORK_ASSIGN),
+				     ret_flags, asssub))) {
+		unqueue_signals();
+		return;
+	    }
+	}
     }
     for (node = firstnode(list); node; incnode(node)) {
 	if (node == stop)