To: vim_dev@googlegroups.com Subject: Patch 9.0.0874 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ 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\") + call TermWait(buf, 50) + call term_sendkeys(buf, "G") + call TermWait(buf, 50) + call term_sendkeys(buf, "\") + + 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 -- Bram@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 ///