From f07a1bd00935b53e73dcbec4e039aef7cc1996b1 Mon Sep 17 00:00:00 2001 From: "Barton E. Schaefer" Date: Sun, 14 Feb 2016 11:13:17 -0800 Subject: 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 --- ChangeLog | 8 ++++++++ Src/Zle/complist.c | 30 ++++++++++++++++++++++-------- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2e60d9eaf..18e4eed59 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2016-02-14 Barton E. Schaefer + + * 37961: Src/Zle/complist.c: 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; + fixes crash on bad memory access + 2016-02-11 Eric Cook * 37913: Completion/BSD/Command/_gstat, 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(); -- cgit 1.4.1