# HG changeset patch # User Christian Brabandt # Date 1713301203 -7200 # Node ID 0cc43bca5bd95ba0180662d6fe07aafdce6602b4 # Parent 057d80758edfa10c9b691ee94b5044d85b831b8a patch 9.1.0341: Problem: a few memory leaks are found Commit: https://github.com/vim/vim/commit/29269a71b5ac8a87c6c4beca35c173a19a2c9398 Author: Christian Brabandt Date: Tue Apr 16 22:44:31 2024 +0200 patch 9.1.0341: Problem: a few memory leaks are found Problem: a few memory leaks are found (LuMingYinDetect ) Solution: properly free the memory Fixes the following problems: - Memory leak in f_maplist() fixes: #14486 - Memory leak in option.c fixes: #14485 - Memory leak in f_resolve() fixes: #14484 - Memory leak in f_autocmd_get() related: #14474 - Memory leak in dict_extend_func() fixes: #14477 fixes: #14238 closes: #14517 Signed-off-by: Christian Brabandt diff --git a/src/autocmd.c b/src/autocmd.c --- a/src/autocmd.c +++ b/src/autocmd.c @@ -3406,7 +3406,10 @@ f_autocmd_get(typval_T *argvars, typval_ event_dict = dict_alloc(); if (event_dict == NULL || list_append_dict(event_list, event_dict) == FAIL) + { + vim_free(pat); return; + } if (dict_add_string(event_dict, "event", event_name) == FAIL || dict_add_string(event_dict, "group", @@ -3421,7 +3424,10 @@ f_autocmd_get(typval_T *argvars, typval_ || dict_add_bool(event_dict, "once", ac->once) == FAIL || dict_add_bool(event_dict, "nested", ac->nested) == FAIL) + { + vim_free(pat); return; + } } } } diff --git a/src/dict.c b/src/dict.c --- a/src/dict.c +++ b/src/dict.c @@ -1300,12 +1300,18 @@ dict_extend_func( action = tv_get_string_chk(&argvars[2]); if (action == NULL) + { + if (is_new) + dict_unref(d1); return; + } for (i = 0; i < 3; ++i) if (STRCMP(action, av[i]) == 0) break; if (i == 3) { + if (is_new) + dict_unref(d1); semsg(_(e_invalid_argument_str), action); return; } diff --git a/src/filepath.c b/src/filepath.c --- a/src/filepath.c +++ b/src/filepath.c @@ -2110,6 +2110,7 @@ f_resolve(typval_T *argvars, typval_T *r if (buf == NULL) { vim_free(p); + vim_free(remain); goto fail; } diff --git a/src/map.c b/src/map.c --- a/src/map.c +++ b/src/map.c @@ -2574,7 +2574,10 @@ f_maplist(typval_T *argvars UNUSED, typv if ((d = dict_alloc()) == NULL) return; if (list_append_dict(rettv->vval.v_list, d) == FAIL) + { + dict_unref(d); return; + } keys_buf = NULL; did_simplify = FALSE; diff --git a/src/option.c b/src/option.c --- a/src/option.c +++ b/src/option.c @@ -853,7 +853,10 @@ set_string_default_esc(char *name, char_ opt_idx = findoption((char_u *)name); if (opt_idx < 0) + { + vim_free(p); return; + } if (options[opt_idx].flags & P_DEF_ALLOCED) vim_free(options[opt_idx].def_val[VI_DEFAULT]); diff --git a/src/testdir/test_listdict.vim b/src/testdir/test_listdict.vim --- a/src/testdir/test_listdict.vim +++ b/src/testdir/test_listdict.vim @@ -1530,4 +1530,10 @@ func Test_indexof() delfunc TestIdx endfunc +func Test_extendnew_leak() + " This used to leak memory + for i in range(100) | silent! call extendnew([], [], []) | endfor + for i in range(100) | silent! call extendnew({}, {}, {}) | endfor +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -705,6 +705,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 341, +/**/ 340, /**/ 339,