# HG changeset patch # User Bram Moolenaar # Date 1649177103 -7200 # Node ID 9099940474007c0e89c21664e6bc7b3d1ff634e4 # Parent 3f09c6b2c21c05740ffa886a3de8efa850e116be patch 8.2.4697: Vim9: crash when adding a duplicate key to a dictionary Commit: https://github.com/vim/vim/commit/0d1f55c044610f627b1617e4cfbf6e094ff60921 Author: Bram Moolenaar Date: Tue Apr 5 17:30:29 2022 +0100 patch 8.2.4697: Vim9: crash when adding a duplicate key to a dictionary Problem: Vim9: crash when adding a duplicate key to a dictionary. Solution: Clear the stack item when it has been moved into the dictionary. (closes #10087) diff --git a/src/testdir/test_vim9_expr.vim b/src/testdir/test_vim9_expr.vim --- a/src/testdir/test_vim9_expr.vim +++ b/src/testdir/test_vim9_expr.vim @@ -2774,6 +2774,9 @@ def Test_expr8_dict() v9.CheckScriptFailure(['vim9script', "var x = {xxx: 1,"], 'E723:', 2) v9.CheckDefAndScriptFailure(["var x = {['a']: xxx}"], ['E1001:', 'E121:'], 1) v9.CheckDefAndScriptFailure(["var x = {a: 1, a: 2}"], 'E721:', 1) + g:key = 'x' + v9.CheckDefExecAndScriptFailure(["var x = {[g:key]: 'text', [g:key]: 'text'}"], 'E721:', 1) + unlet g:key v9.CheckDefExecAndScriptFailure(["var x = g:anint.member"], ['E715:', 'E488:'], 1) v9.CheckDefExecAndScriptFailure(["var x = g:dict_empty.member"], 'E716:', 1) diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -747,6 +747,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 4697, +/**/ 4696, /**/ 4695, diff --git a/src/vim9execute.c b/src/vim9execute.c --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -196,8 +196,10 @@ exe_newdict(int count, ectx_T *ectx) dict_unref(dict); return FAIL; } - item->di_tv = *STACK_TV_BOT(2 * (idx - count) + 1); + tv = STACK_TV_BOT(2 * (idx - count) + 1); + item->di_tv = *tv; item->di_tv.v_lock = 0; + tv->v_type = VAR_UNKNOWN; if (dict_add(dict, item) == FAIL) { // can this ever happen? @@ -5363,7 +5365,7 @@ call_def_function( did_emsg_def += save_did_emsg_def; failed_early: - // Free all local variables, but not arguments. + // Free all arguments and local variables. for (idx = 0; idx < ectx.ec_stack.ga_len; ++idx) clear_tv(STACK_TV(idx)); ex_nesting_level = orig_nesting_level;