mirror of
https://github.com/vim/vim.git
synced 2025-09-28 04:24:06 -04:00
patch 9.0.0874: using freed memory when executing unmenu at more prompt
Problem: Using freed memory when executing unmenu at the more prompt. Solution: Do not clear menus while listing them. (closes #11439)
This commit is contained in:
@@ -3335,3 +3335,7 @@ EXTERN char e_cannot_resize_window_in_another_tab_page[]
|
|||||||
#endif
|
#endif
|
||||||
EXTERN char e_cannot_change_mappings_while_listing[]
|
EXTERN char e_cannot_change_mappings_while_listing[]
|
||||||
INIT(= N_("E1309: Cannot change mappings while listing"));
|
INIT(= N_("E1309: Cannot change mappings while listing"));
|
||||||
|
#if defined(FEAT_MENU)
|
||||||
|
EXTERN char e_cannot_change_menus_while_listing[]
|
||||||
|
INIT(= N_("E1310: Cannot change menus while listing"));
|
||||||
|
#endif
|
||||||
|
34
src/menu.c
34
src/menu.c
@@ -46,6 +46,10 @@ static int s_tearoffs = FALSE;
|
|||||||
static int menu_is_hidden(char_u *name);
|
static int menu_is_hidden(char_u *name);
|
||||||
static int menu_is_tearoff(char_u *name);
|
static int menu_is_tearoff(char_u *name);
|
||||||
|
|
||||||
|
// When non-zero no menu must be added or cleared. Prevents the list of menus
|
||||||
|
// changing while listing them.
|
||||||
|
static int menus_locked = 0;
|
||||||
|
|
||||||
#if defined(FEAT_MULTI_LANG) || defined(FEAT_TOOLBAR)
|
#if defined(FEAT_MULTI_LANG) || defined(FEAT_TOOLBAR)
|
||||||
static char_u *menu_skip_part(char_u *p);
|
static char_u *menu_skip_part(char_u *p);
|
||||||
#endif
|
#endif
|
||||||
@@ -98,6 +102,21 @@ get_root_menu(char_u *name)
|
|||||||
return &root_menu;
|
return &root_menu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If "menus_locked" is set then give an error and return TRUE.
|
||||||
|
* Otherwise return FALSE.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
is_menus_locked(void)
|
||||||
|
{
|
||||||
|
if (menus_locked > 0)
|
||||||
|
{
|
||||||
|
emsg(_(e_cannot_change_menus_while_listing));
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do the :menu command and relatives.
|
* Do the :menu command and relatives.
|
||||||
*/
|
*/
|
||||||
@@ -329,6 +348,9 @@ ex_menu(
|
|||||||
}
|
}
|
||||||
else if (unmenu)
|
else if (unmenu)
|
||||||
{
|
{
|
||||||
|
if (is_menus_locked())
|
||||||
|
goto theend;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Delete menu(s).
|
* Delete menu(s).
|
||||||
*/
|
*/
|
||||||
@@ -357,6 +379,9 @@ ex_menu(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (is_menus_locked())
|
||||||
|
goto theend;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add menu(s).
|
* Add menu(s).
|
||||||
* Replace special key codes.
|
* Replace special key codes.
|
||||||
@@ -1147,11 +1172,14 @@ show_menus(char_u *path_name, int modes)
|
|||||||
}
|
}
|
||||||
vim_free(path_name);
|
vim_free(path_name);
|
||||||
|
|
||||||
// Now we have found the matching menu, and we list the mappings
|
// make sure the list of menus doesn't change while listing them
|
||||||
// Highlight title
|
++menus_locked;
|
||||||
msg_puts_title(_("\n--- Menus ---"));
|
|
||||||
|
|
||||||
|
// list the matching menu mappings
|
||||||
|
msg_puts_title(_("\n--- Menus ---"));
|
||||||
show_menus_recursive(parent, modes, 0);
|
show_menus_recursive(parent, modes, 0);
|
||||||
|
|
||||||
|
--menus_locked;
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -3,6 +3,8 @@
|
|||||||
source check.vim
|
source check.vim
|
||||||
CheckFeature menu
|
CheckFeature menu
|
||||||
|
|
||||||
|
source screendump.vim
|
||||||
|
|
||||||
func Test_load_menu()
|
func Test_load_menu()
|
||||||
try
|
try
|
||||||
source $VIMRUNTIME/menu.vim
|
source $VIMRUNTIME/menu.vim
|
||||||
@@ -568,4 +570,28 @@ func Test_only_modifier()
|
|||||||
tunmenu a.b
|
tunmenu a.b
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_mapclear_while_listing()
|
||||||
|
CheckRunVimInTerminal
|
||||||
|
|
||||||
|
let lines =<< trim END
|
||||||
|
set nocompatible
|
||||||
|
unmenu *
|
||||||
|
for i in range(1, 999)
|
||||||
|
exe 'menu ' .. 'foo.' .. i .. ' bar'
|
||||||
|
endfor
|
||||||
|
au CmdlineLeave : call timer_start(0, {-> execute('unmenu *')})
|
||||||
|
END
|
||||||
|
call writefile(lines, 'Xmenuclear', 'D')
|
||||||
|
let buf = RunVimInTerminal('-S Xmenuclear', {'rows': 10})
|
||||||
|
|
||||||
|
" this was using freed memory
|
||||||
|
call term_sendkeys(buf, ":menu\<CR>")
|
||||||
|
call TermWait(buf, 50)
|
||||||
|
call term_sendkeys(buf, "G")
|
||||||
|
call TermWait(buf, 50)
|
||||||
|
call term_sendkeys(buf, "\<CR>")
|
||||||
|
|
||||||
|
call StopVimInTerminal(buf)
|
||||||
|
endfunc
|
||||||
|
|
||||||
" vim: shiftwidth=2 sts=2 expandtab
|
" vim: shiftwidth=2 sts=2 expandtab
|
||||||
|
@@ -695,6 +695,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
874,
|
||||||
/**/
|
/**/
|
||||||
873,
|
873,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user