1
0
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:
zeertzjq
2022-12-19 16:49:27 +00:00
committed by Bram Moolenaar
parent 07146ad1d3
commit 33e543038b
3 changed files with 20 additions and 2 deletions

View File

@@ -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)

View File

@@ -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);
} }
/* /*

View File

@@ -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,
/**/ /**/