Patch 8.2.3812

5 views
Skip to first unread message

Bram Moolenaar

unread,
Dec 15, 2021, 7:07:26 AM12/15/21
to vim...@googlegroups.com

Patch 8.2.3812
Problem: Vim9: leaking memory in numbered function test.
Solution: Skip "g:" when checking for numbered function. Clean up after
errors properly.
Files: src/userfunc.c


*** ../vim-8.2.3811/src/userfunc.c 2021-12-14 12:06:12.533925687 +0000
--- src/userfunc.c 2021-12-15 12:01:49.976571694 +0000
***************
*** 2136,2141 ****
--- 2136,2151 ----
}

/*
+ * Return TRUE if "name" is a numbered function, ignoring a "g:" prefix.
+ */
+ static int
+ numbered_function(char_u *name)
+ {
+ return isdigit(*name)
+ || (name[0] == 'g' && name[1] == ':' && isdigit(name[2]));
+ }
+
+ /*
* There are two kinds of function names:
* 1. ordinary names, function defined with :function or :def
* 2. numbered functions and lambdas
***************
*** 2146,2152 ****
int
func_name_refcount(char_u *name)
{
! return isdigit(*name) || *name == '<';
}

/*
--- 2156,2162 ----
int
func_name_refcount(char_u *name)
{
! return numbered_function(name) || *name == '<';
}

/*
***************
*** 3956,3961 ****
--- 3966,3973 ----
int flags = 0;
char_u *ret_type = NULL;
ufunc_T *fp = NULL;
+ int fp_allocated = FALSE;
+ int free_fp = FALSE;
int overwrite = FALSE;
dictitem_T *v;
funcdict_T fudi;
***************
*** 4460,4465 ****
--- 4472,4478 ----
fp = alloc_clear(offsetof(ufunc_T, uf_name) + STRLEN(name) + 1);
if (fp == NULL)
goto erret;
+ fp_allocated = TRUE;

if (fudi.fd_dict != NULL)
{
***************
*** 4490,4510 ****
// behave like "dict" was used
flags |= FC_DICT;
}
-
- // insert the new function in the function list
- set_ufunc_name(fp, name);
- if (overwrite)
- {
- hi = hash_find(&func_hashtab, name);
- hi->hi_key = UF2HIKEY(fp);
- }
- else if (hash_add(&func_hashtab, UF2HIKEY(fp)) == FAIL)
- {
- vim_free(fp);
- fp = NULL;
- goto erret;
- }
- fp->uf_refcount = 1;
}
fp->uf_args = newargs;
fp->uf_def_args = default_args;
--- 4503,4508 ----
***************
*** 4527,4533 ****
if (parse_argument_types(fp, &argtypes, varargs) == FAIL)
{
SOURCING_LNUM = lnum_save;
! goto errret_2;
}
varargs = FALSE;

--- 4525,4532 ----
if (parse_argument_types(fp, &argtypes, varargs) == FAIL)
{
SOURCING_LNUM = lnum_save;
! free_fp = fp_allocated;
! goto erret;
}
varargs = FALSE;

***************
*** 4535,4540 ****
--- 4534,4540 ----
if (parse_return_type(fp, ret_type) == FAIL)
{
SOURCING_LNUM = lnum_save;
+ free_fp = fp_allocated;
goto erret;
}
SOURCING_LNUM = lnum_save;
***************
*** 4542,4548 ****
--- 4542,4566 ----
else
fp->uf_def_status = UF_NOT_COMPILED;

+ if (fp_allocated)
+ {
+ // insert the new function in the function list
+ set_ufunc_name(fp, name);
+ if (overwrite)
+ {
+ hi = hash_find(&func_hashtab, name);
+ hi->hi_key = UF2HIKEY(fp);
+ }
+ else if (hash_add(&func_hashtab, UF2HIKEY(fp)) == FAIL)
+ {
+ free_fp = TRUE;
+ goto erret;
+ }
+ fp->uf_refcount = 1;
+ }
+
fp->uf_lines = newlines;
+ newlines.ga_data = NULL;
if ((flags & FC_CLOSURE) != 0)
{
if (register_closure(fp) == FAIL)
***************
*** 4593,4598 ****
--- 4611,4621 ----
ga_clear_strings(&newlines);
if (fp != NULL)
VIM_CLEAR(fp->uf_arg_types);
+ if (free_fp)
+ {
+ vim_free(fp);
+ fp = NULL;
+ }
ret_free:
ga_clear_strings(&argtypes);
vim_free(line_to_free);
***************
*** 4813,4819 ****
if (eap->nextcmd != NULL)
*p = NUL;

! if (isdigit(*name) && fudi.fd_dict == NULL)
{
if (!eap->skip)
semsg(_(e_invarg2), eap->arg);
--- 4836,4842 ----
if (eap->nextcmd != NULL)
*p = NUL;

! if (numbered_function(name) && fudi.fd_dict == NULL)
{
if (!eap->skip)
semsg(_(e_invarg2), eap->arg);
***************
*** 4881,4887 ****
if (name == NULL || !func_name_refcount(name))
return;
fp = find_func(name, FALSE, NULL);
! if (fp == NULL && isdigit(*name))
{
#ifdef EXITFREE
if (!entered_free_all_mem)
--- 4904,4910 ----
if (name == NULL || !func_name_refcount(name))
return;
fp = find_func(name, FALSE, NULL);
! if (fp == NULL && numbered_function(name))
{
#ifdef EXITFREE
if (!entered_free_all_mem)
***************
*** 4924,4930 ****
fp = find_func(name, FALSE, NULL);
if (fp != NULL)
++fp->uf_refcount;
! else if (isdigit(*name))
// Only give an error for a numbered function.
// Fail silently, when named or lambda function isn't found.
internal_error("func_ref()");
--- 4947,4953 ----
fp = find_func(name, FALSE, NULL);
if (fp != NULL)
++fp->uf_refcount;
! else if (numbered_function(name))
// Only give an error for a numbered function.
// Fail silently, when named or lambda function isn't found.
internal_error("func_ref()");
*** ../vim-8.2.3811/src/version.c 2021-12-14 20:26:49.658164887 +0000
--- src/version.c 2021-12-14 20:55:55.637521221 +0000
***************
*** 751,752 ****
--- 751,754 ----
{ /* Add new patch number below this line */
+ /**/
+ 3812,
/**/

--
hundred-and-one symptoms of being an internet addict:
35. Your husband tells you he's had that beard for 2 months.

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
Reply all
Reply to author
Forward
0 new messages