summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2022-12-08 12:00:50 +0000
committerBram Moolenaar <Bram@vim.org>2022-12-08 12:00:50 +0000
commit038e6d20e680ce8c850d07f6b035c4e1904c1201 (patch)
tree6d91f0c3505d285296e0c4078cd8e2e7775e08a3
parent84dbf855fb2d883481f74ad0ccf3df3f8837e6bf (diff)
patch 9.0.1030: using freed memory with the cmdline popup menuv9.0.1030
Problem: Using freed memory with the cmdline popup menu. Solution: Clear the popup menu when clearing the matches. (closes #11677)
-rw-r--r--src/cmdexpand.c19
-rw-r--r--src/testdir/dumps/Test_wildmenu_pum_clear_entries_1.dump10
-rw-r--r--src/testdir/test_cmdline.vim15
-rw-r--r--src/version.c2
4 files changed, 41 insertions, 5 deletions
diff --git a/src/cmdexpand.c b/src/cmdexpand.c
index 228d4bc095..3e2ecb3738 100644
--- a/src/cmdexpand.c
+++ b/src/cmdexpand.c
@@ -369,7 +369,8 @@ cmdline_pum_create(
/*
* Display the cmdline completion matches in a popup menu
*/
-void cmdline_pum_display(void)
+ void
+cmdline_pum_display(void)
{
pum_display(compl_match_array, compl_match_arraysize, compl_selected);
}
@@ -377,7 +378,8 @@ void cmdline_pum_display(void)
/*
* Returns TRUE if the cmdline completion popup menu is being displayed.
*/
-int cmdline_pum_active(void)
+ int
+cmdline_pum_active(void)
{
return pum_visible() && compl_match_array != NULL;
}
@@ -386,7 +388,8 @@ int cmdline_pum_active(void)
* Remove the cmdline completion popup menu (if present), free the list of
* items and refresh the screen.
*/
-void cmdline_pum_remove(void)
+ void
+cmdline_pum_remove(void)
{
int save_p_lz = p_lz;
int save_KeyTyped = KeyTyped;
@@ -403,7 +406,8 @@ void cmdline_pum_remove(void)
KeyTyped = save_KeyTyped;
}
-void cmdline_pum_cleanup(cmdline_info_T *cclp)
+ void
+cmdline_pum_cleanup(cmdline_info_T *cclp)
{
cmdline_pum_remove();
wildmenu_cleanup(cclp);
@@ -413,7 +417,8 @@ void cmdline_pum_cleanup(cmdline_info_T *cclp)
* Returns the starting column number to use for the cmdline completion popup
* menu.
*/
-int cmdline_compl_startcol(void)
+ int
+cmdline_compl_startcol(void)
{
return compl_startcol;
}
@@ -975,6 +980,10 @@ ExpandOne(
FreeWild(xp->xp_numfiles, xp->xp_files);
xp->xp_numfiles = -1;
VIM_CLEAR(orig_save);
+
+ // The entries from xp_files may be used in the PUM, remove it.
+ if (compl_match_array != NULL)
+ cmdline_pum_remove();
}
findex = 0;
diff --git a/src/testdir/dumps/Test_wildmenu_pum_clear_entries_1.dump b/src/testdir/dumps/Test_wildmenu_pum_clear_entries_1.dump
new file mode 100644
index 0000000000..b5825eb195
--- /dev/null
+++ b/src/testdir/dumps/Test_wildmenu_pum_clear_entries_1.dump
@@ -0,0 +1,10 @@
+| +0#0000001#e0e0e08|!| @14| +0#0000000#0000001| +0&#ffffff0@56
+| +0#0000001#ffd7ff255|#| @14| +0#0000000#a8a8a8255| +0#4040ff13#ffffff0@56
+| +0#0000001#ffd7ff255|&| @14| +0#0000000#a8a8a8255| +0#4040ff13#ffffff0@56
+| +0#0000001#ffd7ff255|*| @14| +0#0000000#a8a8a8255| +0#4040ff13#ffffff0@56
+| +0#0000001#ffd7ff255|+@1| @13| +0#0000000#a8a8a8255| +0#4040ff13#ffffff0@56
+| +0#0000001#ffd7ff255|-@1| @13| +0#0000000#a8a8a8255| +0#4040ff13#ffffff0@56
+| +0#0000001#ffd7ff255|<| @14| +0#0000000#a8a8a8255| +0#4040ff13#ffffff0@56
+| +0#0000001#ffd7ff255|=| @14| +0#0000000#a8a8a8255| +0#4040ff13#ffffff0@56
+| +0#0000001#ffd7ff255|>| @14| +0#0000000#a8a8a8255| +0#4040ff13#ffffff0@56
+|:+0#0000000&|!> @72
diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim
index ddc235d1e7..28f845a9ad 100644
--- a/src/testdir/test_cmdline.vim
+++ b/src/testdir/test_cmdline.vim
@@ -2485,6 +2485,21 @@ func Test_wildmenu_pum_from_terminal()
call StopVimInTerminal(buf)
endfunc
+func Test_wildmenu_pum_clear_entries()
+ " This was using freed memory. Run in a terminal to get the pum to update.
+ let lines =<< trim END
+ set wildoptions=pum
+ set wildchar=<C-E>
+ END
+ call writefile(lines, 'XwildmenuTest', 'D')
+ let buf = RunVimInTerminal('-S XwildmenuTest', #{rows: 10})
+
+ call term_sendkeys(buf, ":\<C-E>\<C-E>")
+ call VerifyScreenDump(buf, 'Test_wildmenu_pum_clear_entries_1', {})
+
+ set wildoptions& wildchar&
+endfunc
+
" Test for completion after a :substitute command followed by a pipe (|)
" character
func Test_cmdline_complete_substitute()
diff --git a/src/version.c b/src/version.c
index 469116da33..f4399e5984 100644
--- a/src/version.c
+++ b/src/version.c
@@ -696,6 +696,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1030,
+/**/
1029,
/**/
1028,