about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBarton E. Schaefer <schaefer@zsh.org>2017-10-08 18:08:09 -0700
committerBarton E. Schaefer <schaefer@zsh.org>2017-10-08 18:08:09 -0700
commitb84d69cf5299bf7985b72d25a589b29650cd9b26 (patch)
tree8c264a6e9bbbe18f52c914b14406808e6a9ef419
parent82c26793e4c8e1a9bef7bbc19197db18a9f8d80d (diff)
downloadzsh-b84d69cf5299bf7985b72d25a589b29650cd9b26.tar.gz
zsh-b84d69cf5299bf7985b72d25a589b29650cd9b26.tar.xz
zsh-b84d69cf5299bf7985b72d25a589b29650cd9b26.zip
41828, 41830: skip SHFILEEXPANSION for new nodes added by stringsubst() in prefork()
-rw-r--r--ChangeLog7
-rw-r--r--Src/subst.c19
-rw-r--r--Test/E01options.ztst12
3 files changed, 36 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index a2c6e9daa..7b80e6ac6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2017-10-08  Barton E. Schaefer  <schaefer@zsh.org>
+
+	* 41830: Test/E01options.ztst: test for 41828.
+
+	* 41828: Src/subst.c: skip SHFILEEXPANSION for new nodes added
+	by stringsubst() in prefork().
+
 2017-10-07  Oliver Kiddle  <opk@zsh.org>
 
 	* 41827: Completion/Zsh/Context/_brace_parameter: correct
diff --git a/Src/subst.c b/Src/subst.c
index 2d3eeb2c3..8c290cccf 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -106,15 +106,20 @@ prefork(LinkList list, int flags, int *ret_flags)
 	ret_flags = &ret_flags_local; /* will be discarded */
 
     queue_signals();
-    for (node = firstnode(list); node; incnode(node)) {
+    node = firstnode(list);
+    while (node) {
+	LinkNode nextnode = 0;
 	if ((flags & (PREFORK_SINGLE|PREFORK_ASSIGN)) == PREFORK_ASSIGN &&
 	    (insnode = keyvalpairelement(list, node))) {
 	    node = insnode;
+	    incnode(node);
 	    *ret_flags |= PREFORK_KEY_VALUE;
 	    continue;
 	}
-	if (errflag)
+	if (errflag) {
+	    unqueue_signals();
 	    return;
+	}
 	if (isset(SHFILEEXPANSION)) {
 	    /*
 	     * Here and below we avoid taking the address
@@ -132,6 +137,12 @@ 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),
@@ -139,6 +150,10 @@ prefork(LinkList list, int flags, int *ret_flags)
 	    unqueue_signals();
 	    return;
 	}
+	if (isset(SHFILEEXPANSION))
+	    node = nextnode;
+	else
+	    incnode(node);
     }
     for (node = firstnode(list); node; incnode(node)) {
 	if (node == stop)
diff --git a/Test/E01options.ztst b/Test/E01options.ztst
index 8101ff539..6929f5140 100644
--- a/Test/E01options.ztst
+++ b/Test/E01options.ztst
@@ -1026,6 +1026,18 @@
 >$lspath $lspath =
 >$lspath
 
+  () {
+    emulate -L sh
+    v='~/one ~/two'
+    print -l -- $v $v
+  }
+0:SH_FILE_EXPANSION option with GLOB_SUBST et al.
+F:Regression test for workers/41811
+>~/one
+>~/two
+>~/one
+>~/two
+
   testpat() {
     if [[ $1 = ${~2} ]]; then print $1 $2 yes; else print $1 $2 no; fi
   }