]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.2.0571: Vim9: memory leak in compile_nested_function() on failure v9.2.0571
authorthinca <thinca@gmail.com>
Sun, 31 May 2026 18:28:34 +0000 (18:28 +0000)
committerChristian Brabandt <cb@256bit.org>
Sun, 31 May 2026 18:28:34 +0000 (18:28 +0000)
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>
src/version.c
src/vim9compile.c

index 15a4d34e9cd3e9b36a48c34f40328262434865f6..a90dc1cb9b4771c059ee95d4d2d307a58c7f10e6 100644 (file)
@@ -729,6 +729,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    571,
 /**/
     570,
 /**/
index cbee429763a5f8189eec287ef064a77a003b5d14..aa9384bbe99eb64ba74e348f3433e163a28a165a 100644 (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);
     }