about summary refs log tree commit diff
path: root/Src
diff options
context:
space:
mode:
authorPeter Stephenson <p.w.stephenson@ntlworld.com>2013-08-02 18:58:35 +0100
committerPeter Stephenson <p.w.stephenson@ntlworld.com>2013-08-02 18:58:35 +0100
commit568e0db7a964feefa45061967d0c7079a0e59c1e (patch)
tree534af0aa0df6c685313733628abc8a5cf628a60f /Src
parenta175e051665b84f1b0286441677cb9f2c478a7bd (diff)
downloadzsh-568e0db7a964feefa45061967d0c7079a0e59c1e.tar.gz
zsh-568e0db7a964feefa45061967d0c7079a0e59c1e.tar.xz
zsh-568e0db7a964feefa45061967d0c7079a0e59c1e.zip
31611: attempt to fix crash completing redirection in do loop
Diffstat (limited to 'Src')
-rw-r--r--Src/Zle/zle_tricky.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c
index 78a9fa490..610055c64 100644
--- a/Src/Zle/zle_tricky.c
+++ b/Src/Zle/zle_tricky.c
@@ -1095,6 +1095,7 @@ get_comp_string(void)
      * the command word is not at index zero in the array.
      */
     int redirpos;
+    int noword;
     char *s = NULL, *tmp, *p, *tt = NULL, rdop[20];
     char *linptr, *u;
 
@@ -1165,7 +1166,7 @@ get_comp_string(void)
     * and whatnot. */
 
     do {
-        qsub = 0;
+        qsub = noword = 0;
 
 	lincmd = ((incmdpos && !ins && !incond) ||
 		  (oins == 2 && wordpos == 2) ||
@@ -1239,6 +1240,19 @@ get_comp_string(void)
 	     * leave the loop.                                           */
 	    if (tt)
 		break;
+	    if (ins < 2) {
+		/*
+		 * Don't add this as a word, because we're about to start
+		 * a new command line: pretend there's no string here.
+		 * We don't dare do this if we're using one of the
+		 * *really* gross hacks with ins to get later words
+		 * to look like command words, because we don't
+		 * understand how they work.  Quite possibly we
+		 * should be using a mechanism like the one here rather
+		 * than the ins thing.
+		 */
+		noword = 1;
+	    }
 	    /* Otherwise reset the variables we are collecting data in. */
 	    wordpos = cp = rd = ins = redirpos = 0;
 	    tt0 = NULLTOK;
@@ -1253,6 +1267,14 @@ get_comp_string(void)
 	    /* If everything before is a redirection, don't reset the index */
 	    if (wordpos != redirpos)
 		wordpos = redirpos = 0;
+	} else if (tok == SEPER) {
+	    /*
+	     * A following DOLOOP should cause us to reset to the start
+	     * of the command line.  For some reason we only recognise
+	     * DOLOOP for this purpose (above) if ins is set.  Why?
+	     * Don't ask pointless questions.
+	     */
+	    ins = 1;
 	}
 	if (!lexflags && tt0 == NULLTOK) {
 	    /* This is done when the lexer reached the word the cursor is on. */
@@ -1322,7 +1344,7 @@ get_comp_string(void)
 	    else if (tok == DAMPER)
 		tokstr = "&&";
 	}
-	if (!tokstr)
+	if (!tokstr || noword)
 	    continue;
 	/* Hack to allow completion after `repeat n do'. */
 	if (oins == 2 && !wordpos && !strcmp(tokstr, "do"))