summaryrefslogtreecommitdiff
path: root/Src/Zle/complist.c
diff options
context:
space:
mode:
authorBarton E. Schaefer <schaefer@zsh.org>2016-02-14 11:13:17 -0800
committerBarton E. Schaefer <schaefer@zsh.org>2016-02-14 11:13:17 -0800
commitf07a1bd00935b53e73dcbec4e039aef7cc1996b1 (patch)
tree9c2b3325c6df4fa2515e85409214ec9d582b7f5b /Src/Zle/complist.c
parent1b923f69c7dac0e0a2c71c62bbcdb2d2de5128db (diff)
downloadzsh-f07a1bd00935b53e73dcbec4e039aef7cc1996b1.tar.gz
zsh-f07a1bd00935b53e73dcbec4e039aef7cc1996b1.zip
37961: fix crash on bad memory access
In interactive menuselection, use of "compadd -x" (e.g. the "warnings" zstyle) may have replaced the completion list, so skip highlighting of the current selection until a subsequent keystroke has regenerated the original listing
Diffstat (limited to 'Src/Zle/complist.c')
-rw-r--r--Src/Zle/complist.c30
1 files changed, 22 insertions, 8 deletions
diff --git a/Src/Zle/complist.c b/Src/Zle/complist.c
index 937e1d141..162436b55 100644
--- a/Src/Zle/complist.c
+++ b/Src/Zle/complist.c
@@ -34,8 +34,9 @@
/* Information about the list shown. */
/*
- * noselect: 1 if complistmatches indicated we shouldn't do selection.
- * Tested in domenuselect.
+ * noselect: 1 if complistmatches indicated we shouldn't do selection;
+ * -1 if interactive mode needs to reset the selection list.
+ * Tested in domenuselect, and in complistmatches to skip redraw.
* mselect: Local copy of the index of the currently selected match.
* Initialised to the gnum entry of the current match for
* each completion.
@@ -1980,7 +1981,8 @@ complistmatches(UNUSED(Hookdef dummy), Chdata dat)
}
#endif
- noselect = 0;
+ if (noselect > 0)
+ noselect = 0;
if ((minfo.asked == 2 && mselect < 0) || nlnct >= zterm_lines) {
showinglist = 0;
@@ -2078,9 +2080,11 @@ complistmatches(UNUSED(Hookdef dummy), Chdata dat)
last_cap = (char *) zhalloc(max_caplen + 1);
*last_cap = '\0';
- if (!mnew && inselect && onlnct == nlnct && mlbeg >= 0 && mlbeg == molbeg)
- singledraw();
- else if (!compprintlist(mselect >= 0) || !clearflag)
+ if (!mnew && inselect &&
+ onlnct == nlnct && mlbeg >= 0 && mlbeg == molbeg) {
+ if (!noselect)
+ singledraw();
+ } else if (!compprintlist(mselect >= 0) || !clearflag)
noselect = 1;
onlnct = nlnct;
@@ -2093,7 +2097,7 @@ complistmatches(UNUSED(Hookdef dummy), Chdata dat)
popheap();
opts[EXTENDEDGLOB] = extendedglob;
- return noselect;
+ return (noselect < 0 ? 0 : noselect);
}
static int
@@ -2547,14 +2551,23 @@ domenuselect(Hookdef dummy, Chdata dat)
} else {
statusline = NULL;
}
+ if (noselect < 0) {
+ showinglist = clearlist = 0;
+ clearflag = 1;
+ }
zrefresh();
statusline = NULL;
inselect = 1;
+ selected = 1;
if (noselect) {
+ if (noselect < 0) {
+ /* no selection until after processing keystroke */
+ noselect = 0;
+ goto getk;
+ }
broken = 1;
break;
}
- selected = 1;
if (!i) {
i = mcols * mlines;
while (i--)
@@ -2752,6 +2765,7 @@ domenuselect(Hookdef dummy, Chdata dat)
if (nmessages) {
showinglist = -2;
zrefresh();
+ noselect = -1;
} else {
trashzle();
zsetterm();