about summary refs log tree commit diff
path: root/Src
diff options
context:
space:
mode:
authorPeter Stephenson <p.w.stephenson@ntlworld.com>2019-12-31 18:35:06 +0000
committerPeter Stephenson <p.w.stephenson@ntlworld.com>2019-12-31 18:35:06 +0000
commitc557cee1a65f5668846818aedb03d4d0bee60c02 (patch)
tree6ed3ca45360173930195a4e4a15ab5dea5356453 /Src
parentf3d18c3fb5ef431962a3ed2062f637e253b3d975 (diff)
downloadzsh-c557cee1a65f5668846818aedb03d4d0bee60c02.tar.gz
zsh-c557cee1a65f5668846818aedb03d4d0bee60c02.tar.xz
zsh-c557cee1a65f5668846818aedb03d4d0bee60c02.zip
24581: Fix array assignments in shell word splitting and completion.
Assignments after the first were not recognised as such as without
the full parser the state didn't return to command position.
Fix this in bufferwords() and the completion miniparser.
Diffstat (limited to 'Src')
-rw-r--r--Src/Zle/zle_tricky.c4
-rw-r--r--Src/hist.c10
2 files changed, 13 insertions, 1 deletions
diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c
index 2b25d6b2e..fdd168763 100644
--- a/Src/Zle/zle_tricky.c
+++ b/Src/Zle/zle_tricky.c
@@ -1236,8 +1236,10 @@ get_comp_string(void)
 	else if (tok == OUTPAR) {
 	    if (parct)
 		parct--;
-	    else
+	    else if (linarr) {
 		linarr = 0;
+		incmdpos = 1;
+	    }
 	}
 	if (inredir && IS_REDIROP(tok)) {
             rdstr = rdstrbuf;
diff --git a/Src/hist.c b/Src/hist.c
index 74116e82f..5281e8718 100644
--- a/Src/hist.c
+++ b/Src/hist.c
@@ -3321,6 +3321,7 @@ bufferwords(LinkList list, char *buf, int *index, int flags)
     int owb = wb, owe = we, oadx = addedx, onc = nocomments;
     int ona = noaliases, ocs = zlemetacs, oll = zlemetall;
     int forloop = 0, rcquotes = opts[RCQUOTES];
+    int envarray = 0;
     char *p, *addedspaceptr;
 
     if (!list)
@@ -3404,6 +3405,14 @@ bufferwords(LinkList list, char *buf, int *index, int flags)
 	ctxtlex();
 	if (tok == ENDINPUT || tok == LEXERR)
 	    break;
+	/*
+	 * After an array assignment, return to the initial
+	 * start-of-command state.  There could be a second ENVARRAY.
+	 */
+	if (tok == OUTPAR && envarray) {
+	    incmdpos = 1;
+	    envarray = 0;
+	}
 	if (tok == FOR) {
 	    /*
 	     * The way for (( expr1 ; expr2; expr3 )) is parsed is:
@@ -3441,6 +3450,7 @@ bufferwords(LinkList list, char *buf, int *index, int flags)
 	    switch (tok) {
 	    case ENVARRAY:
 		p = dyncat(tokstr, "=(");
+		envarray = 1;
 		break;
 
 	    case DINPAR: