forked from aniani/vim
patch 9.0.1079: leaking memory when defining a user command fails
Problem: Leaking memory when defining a user command fails. Solution: Free "compl_arg" when needed. (closes #11726)
This commit is contained in:
@@ -342,6 +342,11 @@ func Test_CmdErrors()
|
|||||||
call assert_fails('com DoCmd :', 'E174:')
|
call assert_fails('com DoCmd :', 'E174:')
|
||||||
comclear
|
comclear
|
||||||
call assert_fails('delcom DoCmd', 'E184:')
|
call assert_fails('delcom DoCmd', 'E184:')
|
||||||
|
|
||||||
|
" These used to leak memory
|
||||||
|
call assert_fails('com! -complete=custom,CustomComplete _ :', 'E182:')
|
||||||
|
call assert_fails('com! -complete=custom,CustomComplete docmd :', 'E183:')
|
||||||
|
call assert_fails('com! -complete=custom,CustomComplete -xxx DoCmd :', 'E181:')
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
func CustomComplete(A, L, P)
|
func CustomComplete(A, L, P)
|
||||||
|
@@ -1167,7 +1167,7 @@ ex_command(exarg_T *eap)
|
|||||||
end = skiptowhite(p);
|
end = skiptowhite(p);
|
||||||
if (uc_scan_attr(p, end - p, &argt, &def, &flags, &compl,
|
if (uc_scan_attr(p, end - p, &argt, &def, &flags, &compl,
|
||||||
&compl_arg, &addr_type_arg) == FAIL)
|
&compl_arg, &addr_type_arg) == FAIL)
|
||||||
return;
|
goto theend;
|
||||||
p = skipwhite(end);
|
p = skipwhite(end);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1179,7 +1179,7 @@ ex_command(exarg_T *eap)
|
|||||||
if (!ends_excmd2(eap->arg, p) && !VIM_ISWHITE(*p))
|
if (!ends_excmd2(eap->arg, p) && !VIM_ISWHITE(*p))
|
||||||
{
|
{
|
||||||
emsg(_(e_invalid_command_name));
|
emsg(_(e_invalid_command_name));
|
||||||
return;
|
goto theend;
|
||||||
}
|
}
|
||||||
end = p;
|
end = p;
|
||||||
name_len = (int)(end - name);
|
name_len = (int)(end - name);
|
||||||
@@ -1188,13 +1188,19 @@ ex_command(exarg_T *eap)
|
|||||||
// we are listing commands
|
// we are listing commands
|
||||||
p = skipwhite(end);
|
p = skipwhite(end);
|
||||||
if (!has_attr && ends_excmd2(eap->arg, p))
|
if (!has_attr && ends_excmd2(eap->arg, p))
|
||||||
|
{
|
||||||
uc_list(name, end - name);
|
uc_list(name, end - name);
|
||||||
|
}
|
||||||
else if (!ASCII_ISUPPER(*name))
|
else if (!ASCII_ISUPPER(*name))
|
||||||
|
{
|
||||||
emsg(_(e_user_defined_commands_must_start_with_an_uppercase_letter));
|
emsg(_(e_user_defined_commands_must_start_with_an_uppercase_letter));
|
||||||
|
}
|
||||||
else if ((name_len == 1 && *name == 'X')
|
else if ((name_len == 1 && *name == 'X')
|
||||||
|| (name_len <= 4
|
|| (name_len <= 4
|
||||||
&& STRNCMP(name, "Next", name_len > 4 ? 4 : name_len) == 0))
|
&& STRNCMP(name, "Next", name_len > 4 ? 4 : name_len) == 0))
|
||||||
|
{
|
||||||
emsg(_(e_reserved_name_cannot_be_used_for_user_defined_command));
|
emsg(_(e_reserved_name_cannot_be_used_for_user_defined_command));
|
||||||
|
}
|
||||||
else if (compl > 0 && (argt & EX_EXTRA) == 0)
|
else if (compl > 0 && (argt & EX_EXTRA) == 0)
|
||||||
{
|
{
|
||||||
// Some plugins rely on silently ignoring the mistake, only make this
|
// Some plugins rely on silently ignoring the mistake, only make this
|
||||||
@@ -1215,7 +1221,12 @@ ex_command(exarg_T *eap)
|
|||||||
uc_add_command(name, end - name, p, argt, def, flags, compl, compl_arg,
|
uc_add_command(name, end - name, p, argt, def, flags, compl, compl_arg,
|
||||||
addr_type_arg, eap->forceit);
|
addr_type_arg, eap->forceit);
|
||||||
vim_free(tofree);
|
vim_free(tofree);
|
||||||
|
|
||||||
|
return; // success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
theend:
|
||||||
|
vim_free(compl_arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -695,6 +695,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1079,
|
||||||
/**/
|
/**/
|
||||||
1078,
|
1078,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user