mirror of
https://github.com/vim/vim.git
synced 2025-09-25 03:54:15 -04:00
patch 9.0.0877: using freed memory with :comclear while listing commands
Problem: Using freed memory with :comclear while listing commands. Solution: Bail out when the command list has changed. (closes #11440)
This commit is contained in:
@@ -31,6 +31,9 @@ typedef struct ucmd
|
||||
// List of all user commands.
|
||||
static garray_T ucmds = {0, 0, sizeof(ucmd_T), 4, NULL};
|
||||
|
||||
// When non-zero it is not allowed to add or remove user commands
|
||||
static int ucmd_locked = 0;
|
||||
|
||||
#define USER_CMD(i) (&((ucmd_T *)(ucmds.ga_data))[i])
|
||||
#define USER_CMD_GA(gap, i) (&((ucmd_T *)((gap)->ga_data))[i])
|
||||
|
||||
@@ -499,6 +502,9 @@ uc_list(char_u *name, size_t name_len)
|
||||
long a;
|
||||
garray_T *gap;
|
||||
|
||||
// don't allow for adding or removing user commands here
|
||||
++ucmd_locked;
|
||||
|
||||
// In cmdwin, the alternative buffer should be used.
|
||||
gap = &prevwin_curwin()->w_buffer->b_ucmds;
|
||||
for (;;)
|
||||
@@ -656,6 +662,8 @@ uc_list(char_u *name, size_t name_len)
|
||||
|
||||
if (!found)
|
||||
msg(_("No user-defined commands found"));
|
||||
|
||||
--ucmd_locked;
|
||||
}
|
||||
|
||||
char *
|
||||
@@ -1222,6 +1230,21 @@ ex_comclear(exarg_T *eap UNUSED)
|
||||
uc_clear(&curbuf->b_ucmds);
|
||||
}
|
||||
|
||||
/*
|
||||
* If ucmd_locked is set give an error and return TRUE.
|
||||
* Otherwise return FALSE.
|
||||
*/
|
||||
static int
|
||||
is_ucmd_locked(void)
|
||||
{
|
||||
if (ucmd_locked > 0)
|
||||
{
|
||||
emsg(_(e_cannot_change_user_commands_while_listing));
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear all user commands for "gap".
|
||||
*/
|
||||
@@ -1231,6 +1254,9 @@ uc_clear(garray_T *gap)
|
||||
int i;
|
||||
ucmd_T *cmd;
|
||||
|
||||
if (is_ucmd_locked())
|
||||
return;
|
||||
|
||||
for (i = 0; i < gap->ga_len; ++i)
|
||||
{
|
||||
cmd = USER_CMD_GA(gap, i);
|
||||
@@ -1285,6 +1311,9 @@ ex_delcommand(exarg_T *eap)
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_ucmd_locked())
|
||||
return;
|
||||
|
||||
vim_free(cmd->uc_name);
|
||||
vim_free(cmd->uc_rep);
|
||||
# if defined(FEAT_EVAL)
|
||||
|
Reference in New Issue
Block a user