]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.2.0774: Memory leak in f_getscriptinfo() on alloc failure v9.2.0774
authorChristian Brabandt <cb@256bit.org>
Thu, 2 Jul 2026 19:42:36 +0000 (19:42 +0000)
committerChristian Brabandt <cb@256bit.org>
Thu, 2 Jul 2026 19:42:36 +0000 (19:42 +0000)
Problem:  Memory leak in the script info code on allocation failure
Solution: Route the failures through the existing cleanup with "goto
          theend", and unref var_dict and the functions list when
          dict_add_dict()/dict_add_list() fail.

related: #20668

Supported by AI.

Signed-off-by: Christian Brabandt <cb@256bit.org>
src/scriptfile.c
src/version.c

index a9b2574934cf469814ebeb6f0cc5f1a52b605e8d..c32c73ec0314cf65fe10243f0f22e1c013fd392a 100644 (file)
@@ -2342,31 +2342,46 @@ f_getscriptinfo(typval_T *argvars, typval_T *rettv)
            continue;
 
        if ((d = dict_alloc()) == NULL
-               || list_append_dict(l, d) == FAIL
-               || dict_add_string(d, "name", si->sn_name) == FAIL
+               || list_append_dict(l, d) == FAIL)
+       {
+           dict_unref(d);
+           goto theend;
+       }
+       if (dict_add_string(d, "name", si->sn_name) == FAIL
                || dict_add_number(d, "sid", i) == FAIL
                || dict_add_number(d, "sourced", si->sn_sourced_sid) == FAIL
                || dict_add_number(d, "version", si->sn_version) == FAIL
                || dict_add_bool(d, "autoload",
                                si->sn_state == SN_STATE_NOT_LOADED) == FAIL)
-           return;
+           goto theend;
 
        // When a script ID is specified, return information about only the
        // specified script, and add the script-local variables and functions.
        if (sid > 0)
        {
            dict_T      *var_dict;
+           list_T      *fn_list;
 
            var_dict = dict_copy(&si->sn_vars->sv_dict, TRUE, TRUE,
                                                                get_copyID());
-           if (var_dict == NULL
-                   || dict_add_dict(d, "variables", var_dict) == FAIL
-                   || dict_add_list(d, "functions",
-                                       get_script_local_funcs(sid)) == FAIL)
-               return;
+           if (var_dict == NULL)
+               goto theend;
+           if (dict_add_dict(d, "variables", var_dict) == FAIL)
+           {
+               dict_unref(var_dict);
+               goto theend;
+           }
+           --var_dict->dv_refcount;
+           fn_list = get_script_local_funcs(sid);
+           if (fn_list == NULL || dict_add_list(d, "functions", fn_list) == FAIL)
+           {
+               list_unref(fn_list);
+               goto theend;
+           }
        }
     }
 
+theend:
     vim_regfree(regmatch.regprog);
     vim_free(pat);
 }
index 7e0fe9136037ed33c5f7375ab662ac043376e8b1..a8b8c103dc3a73a146c7e2ddff0b048cf7018a01 100644 (file)
@@ -759,6 +759,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    774,
 /**/
     773,
 /**/