From b43fee4c096e4b2fdd79e3e56e8fb0575d1c5e3f Mon Sep 17 00:00:00 2001 From: Yee Cheng Chin Date: Thu, 6 Oct 2022 16:35:26 -0700 Subject: [PATCH] Fix :emenu crash when it's associated with a macaction in a non-valid mode The existing emenu code has this odd exception where if you invoke it on a menu with bound in Vim, and has a macaction, it will call the macaction instead. However, it's not properly handling the situation when the menu is not bound for the mode and would crash when deferencing a null string ptr. Move it to the proper spot and fix up a previous upstream merge mistake (in Vim upstream, when you call :emenu on a menu item it just does nothing now, instead of complaining about it) so that it all works correctly. --- src/menu.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/src/menu.c b/src/menu.c index d57352c92d..2a4916b50b 100644 --- a/src/menu.c +++ b/src/menu.c @@ -2376,9 +2376,24 @@ execute_menu(exarg_T *eap, vimmenu_T *menu, int mode_idx) if (idx == MENU_INDEX_INVALID || eap == NULL) idx = MENU_INDEX_NORMAL; - if (menu->strings[idx] != NULL && menu->strings[idx][0] != NUL - && (menu->modes & (1 << idx))) + if (menu->strings[idx] != NULL && (menu->modes & (1 << idx))) { +#ifdef FEAT_GUI_MACVIM + // When a menu is bound to , we let :emenu fall through to execute + // the associated macaction (if one exists) instead. Otherwise, we + // simply execute the associated Vim command. Note that if you + // physically press the menu item (or the associated shortcut key), the + // macaction is always invoked even if the menu isn't bound to . + if (menu->mac_action != NULL && menu->strings[idx] != NULL && menu->strings[idx][0] == NUL) + { + // Count on the fact taht ex_macaction() only looks at eap->arg. + old_arg = eap->arg; + eap->arg = menu->mac_action; + ex_macaction(eap); + eap->arg = old_arg; + } +#endif // FEAT_GUI_MACVIM + // When executing a script or function execute the commands right now. // Also for the window toolbar. // Otherwise put them in the typeahead buffer. @@ -2425,20 +2440,6 @@ execute_menu(exarg_T *eap, vimmenu_T *menu, int mode_idx) default: mode = (char_u *)"Normal"; } -#ifdef FEAT_GUI_MACVIM - if (menu->mac_action != NULL && menu->strings[idx][0] == NUL) - { - // This allows us to bind a menu to an action without mapping to - // anything so that pressing the menu's key equivalent and typing - // ":emenu ..." does the same thing. (HACK: We count on the fact - // that ex_macaction() only looks at eap->arg.) - old_arg = eap->arg; - eap->arg = menu->mac_action; - ex_macaction(eap); - eap->arg = old_arg; - } - else -#endif // FEAT_GUI_MACVIM semsg(_(e_menu_not_defined_for_str_mode), mode); } }