From 37089793b8343548d75b1c856d0606e7bac62387 Mon Sep 17 00:00:00 2001 From: thinca Date: Sun, 31 May 2026 18:28:34 +0000 Subject: [PATCH] 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 Signed-off-by: thinca Signed-off-by: Christian Brabandt --- src/version.c | 2 ++ src/vim9compile.c | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/src/version.c b/src/version.c index 15a4d34e9c..a90dc1cb9b 100644 --- a/src/version.c +++ b/src/version.c @@ -729,6 +729,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 571, /**/ 570, /**/ diff --git a/src/vim9compile.c b/src/vim9compile.c index cbee429763..aa9384bbe9 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -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); }