patch 9.2.0571: Vim9: memory leak in compile_nested_function() on failure

Problem:  compile_nested_function() calls define_function(), which registers
          the new ufunc in func_hashtab with uf_refcount == 1.  For a local
          nested function the caller then reserves a local lvalue and
          generates a FUNCREF instruction; if either step fails, the code
          jumps to the theend label and leaves the ufunc behind with
          refcount 1 and no external reference, leaking it.  This mirrors
          patch 8.2.3951, which fixed the same leak for the "text after
          :enddef" branch a few lines above.
Solution: Call func_ptr_unref() on the ufunc before "goto theend" on both
          failure paths in the local-variable branch (thinca).

closes: #20394

Co-Authored-by: Claude <noreply@anthropic.com>
Signed-off-by: thinca <thinca@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
thinca
2026-05-31 18:28:34 +00:00
committed by Christian Brabandt
parent d0fffdab16
commit 37089793b8
2 changed files with 8 additions and 0 deletions
+2
View File
@@ -729,6 +729,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
571,
/**/
570,
/**/
+6
View File
@@ -1170,9 +1170,15 @@ compile_nested_function(exarg_T *eap, cctx_T *cctx, garray_T *lines_to_free)
lvar = reserve_local(cctx, func_name, name_end - name_start,
ASSIGN_CONST, ufunc->uf_func_type);
if (lvar == NULL)
{
func_ptr_unref(ufunc);
goto theend;
}
if (generate_FUNCREF(cctx, ufunc, NULL, FALSE, 0, &funcref_isn_idx) == FAIL)
{
func_ptr_unref(ufunc);
goto theend;
}
r = generate_STORE(cctx, ISN_STORE, lvar->lv_idx, NULL);
}