From 600d9f35a4e32dc409d185013dc6316fbc0cbf5c Mon Sep 17 00:00:00 2001 From: Sean Dewar <6256228+seandewar@users.noreply.github.com> Date: Thu, 15 Jan 2026 20:22:29 +0000 Subject: [PATCH] vim-patch:9.1.2086: Memory leak when skipping invalid literal dict Problem: memory leak when not evaluating (just parsing) invalid literal dict. Solution: Always clear the key's typval (Sean Dewar) Though "check_typval_is_value(&tv) == FAIL && !evaluate" is maybe never true, also always clear tvs if check_typval_is_value fails; at worst this would be a no-op as their initial types are VAR_UNKNOWN. closes: vim/vim#19178 https://github.com/vim/vim/commit/b10a3e1a20c444ffea34be820e8ceba4b2503287 check_typval_is_value change is for Vim9 script. (from 9.0.2163) N/A patch: vim-patch:9.0.2163: Vim9: type can be assigned to list/dict Co-authored-by: Sean Dewar <6256228+seandewar@users.noreply.github.com> (cherry picked from commit ba1d50fdc37ffd5850f4ee9662d8576b78663d4a) --- src/nvim/eval.c | 4 +--- test/old/testdir/test_listdict.vim | 2 ++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/nvim/eval.c b/src/nvim/eval.c index cee565b2e4..d1359dccb0 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -5233,9 +5233,7 @@ static int eval_dict(char **arg, typval_T *rettv, evalarg_T *const evalarg, bool *arg = skipwhite(*arg + 1); if (eval1(arg, &tv, evalarg) == FAIL) { // Recursive! - if (evaluate) { - tv_clear(&tvkey); - } + tv_clear(&tvkey); goto failret; } if (evaluate) { diff --git a/test/old/testdir/test_listdict.vim b/test/old/testdir/test_listdict.vim index 678734dafb..8f99bc8643 100644 --- a/test/old/testdir/test_listdict.vim +++ b/test/old/testdir/test_listdict.vim @@ -560,6 +560,8 @@ func Test_dict_literal_keys() " why *{} cannot be used for a literal dictionary let blue = 'blue' call assert_equal('6', trim(execute('echo 2 *{blue: 3}.blue'))) + + call assert_fails('eval 1 || #{a:', 'E15:') " used to leak endfunc " Nasty: deepcopy() dict that refers to itself (fails when noref used)