From 568e0db7a964feefa45061967d0c7079a0e59c1e Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Fri, 2 Aug 2013 18:58:35 +0100 Subject: 31611: attempt to fix crash completing redirection in do loop --- Src/Zle/zle_tricky.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'Src') 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")) -- cgit 1.4.1