Patch 9.0.0874
Problem: Using freed memory when executing unmenu at the more prompt.
Solution: Do not clear menus while listing them. (closes #11439)
Files: src/menu.c, src/errors.h, src/testdir/test_menu.vim
*** ../vim-9.0.0873/src/menu.c 2022-09-13 11:55:06.517824775 +0100
--- src/menu.c 2022-11-13 21:01:16.293153857 +0000
***************
*** 46,51 ****
--- 46,55 ----
static int menu_is_hidden(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)
static char_u *menu_skip_part(char_u *p);
#endif
***************
*** 99,104 ****
--- 103,123 ----
}
/*
+ * 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.
*/
void
***************
*** 329,334 ****
--- 348,356 ----
}
else if (unmenu)
{
+ if (is_menus_locked())
+ goto theend;
+
/*
* Delete menu(s).
*/
***************
*** 357,362 ****
--- 379,387 ----
}
else
{
+ if (is_menus_locked())
+ goto theend;
+
/*
* Add menu(s).
* Replace special key codes.
***************
*** 1147,1157 ****
}
vim_free(path_name);
! // Now we have found the matching menu, and we list the mappings
! // Highlight title
! msg_puts_title(_("\n--- Menus ---"));
show_menus_recursive(parent, modes, 0);
return OK;
}
--- 1172,1185 ----
}
vim_free(path_name);
! // make sure the list of menus doesn't change while listing them
! ++menus_locked;
+ // list the matching menu mappings
+ msg_puts_title(_("\n--- Menus ---"));
show_menus_recursive(parent, modes, 0);
+
+ --menus_locked;
return OK;
}
*** ../vim-9.0.0873/src/errors.h 2022-11-13 20:43:14.932366214 +0000
--- src/errors.h 2022-11-13 21:00:03.608917704 +0000
***************
*** 3335,3337 ****
--- 3335,3341 ----
#endif
EXTERN char e_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
*** ../vim-9.0.0873/src/testdir/test_menu.vim 2022-10-10 13:46:09.977158083 +0100
--- src/testdir/test_menu.vim 2022-11-13 20:51:02.656393145 +0000
***************
*** 3,8 ****
--- 3,10 ----
source check.vim
CheckFeature menu
+ source screendump.vim
+
func Test_load_menu()
try
source $VIMRUNTIME/menu.vim
***************
*** 568,571 ****
--- 570,597 ----
tunmenu a.b
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-9.0.0873/src/version.c 2022-11-13 20:43:14.932366214 +0000
--- src/version.c 2022-11-13 20:51:54.484390317 +0000
***************
*** 697,698 ****
--- 697,700 ----
{ /* Add new patch number below this line */
+ /**/
+ 874,
/**/
--
"I don’t know how to make a screenshot" - Richard Stallman, July 2002
(when asked to send a screenshot of his desktop for
unix.se)
/// Bram Moolenaar -- Br...@Moolenaar.net --
http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features --
http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims --
http://ICCF-Holland.org ///