forked from aniani/vim
patch 9.0.0873: using freed memory when executing mapclear at more prompt
Problem: Using freed memory when executing mapclear at the more prompt. Solution: Do not clear mappings while listing them. (closes #11438)
This commit is contained in:
36
src/map.c
36
src/map.c
@@ -24,6 +24,10 @@ static mapblock_T *first_abbr = NULL; // first entry in abbrlist
|
||||
static mapblock_T *(maphash[256]);
|
||||
static int maphash_valid = FALSE;
|
||||
|
||||
// When non-zero then no mappings can be added or removed. Prevents mappings
|
||||
// to change while listing them.
|
||||
static int map_locked = 0;
|
||||
|
||||
/*
|
||||
* Make a hash value for a mapping.
|
||||
* "mode" is the lower 4 bits of the State for the mapping.
|
||||
@@ -150,11 +154,15 @@ showmap(
|
||||
if (message_filtered(mp->m_keys) && message_filtered(mp->m_str))
|
||||
return;
|
||||
|
||||
// Prevent mappings to be cleared while at the more prompt.
|
||||
// Must jump to "theend" instead of returning.
|
||||
++map_locked;
|
||||
|
||||
if (msg_didout || msg_silent != 0)
|
||||
{
|
||||
msg_putchar('\n');
|
||||
if (got_int) // 'q' typed at MORE prompt
|
||||
return;
|
||||
goto theend;
|
||||
}
|
||||
|
||||
mapchars = map_mode_to_chars(mp->m_mode);
|
||||
@@ -200,6 +208,9 @@ showmap(
|
||||
#endif
|
||||
msg_clr_eos();
|
||||
out_flush(); // show one line at a time
|
||||
|
||||
theend:
|
||||
--map_locked;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -298,6 +309,9 @@ list_mappings(
|
||||
int mode,
|
||||
int *did_local)
|
||||
{
|
||||
// Prevent mappings to be cleared while at the more prompt.
|
||||
++map_locked;
|
||||
|
||||
if (p_verbose > 0 && keyround == 1 && seenModifyOtherKeys)
|
||||
msg_puts(_("Seen modifyOtherKeys: true"));
|
||||
|
||||
@@ -337,6 +351,8 @@ list_mappings(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
--map_locked;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -954,6 +970,21 @@ map_clear(
|
||||
map_clear_mode(curbuf, mode, local, abbr);
|
||||
}
|
||||
|
||||
/*
|
||||
* If "map_locked" is set then give an error and return TRUE.
|
||||
* Otherwise return FALSE.
|
||||
*/
|
||||
static int
|
||||
is_map_locked(void)
|
||||
{
|
||||
if (map_locked > 0)
|
||||
{
|
||||
emsg(_(e_cannot_change_mappings_while_listing));
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear all mappings in "mode".
|
||||
*/
|
||||
@@ -968,6 +999,9 @@ map_clear_mode(
|
||||
int hash;
|
||||
int new_hash;
|
||||
|
||||
if (is_map_locked())
|
||||
return;
|
||||
|
||||
validate_maphash();
|
||||
|
||||
for (hash = 0; hash < 256; ++hash)
|
||||
|
Reference in New Issue
Block a user