From: Christian Brabandt Date: Thu, 2 Jul 2026 19:42:36 +0000 (+0000) Subject: patch 9.2.0774: Memory leak in f_getscriptinfo() on alloc failure X-Git-Tag: v9.2.0774^0 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9082201cc218a787e794f74a432c72e70e898542;p=thirdparty%2Fvim.git patch 9.2.0774: Memory leak in f_getscriptinfo() on alloc failure 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 --- diff --git a/src/scriptfile.c b/src/scriptfile.c index a9b2574934..c32c73ec03 100644 --- a/src/scriptfile.c +++ b/src/scriptfile.c @@ -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); } diff --git a/src/version.c b/src/version.c index 7e0fe91360..a8b8c103dc 100644 --- a/src/version.c +++ b/src/version.c @@ -759,6 +759,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 774, /**/ 773, /**/