To: vim_dev@googlegroups.com Subject: Patch 8.2.2920 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.2920 Problem: Still a way to shadow a builtin function. (Yasuhiro Matsumoto) Solution: Check the key when using extend(). (issue #8302) Files: src/eval.c, src/dict.c, src/proto/dict.pro, src/testdir/test_functions.vim *** ../vim-8.2.2919/src/eval.c 2021-05-31 22:15:22.126560003 +0200 --- src/eval.c 2021-06-01 21:09:38.880249532 +0200 *************** *** 1462,1473 **** semsg(_(e_dictkey), lp->ll_newkey); return; } ! if ((lp->ll_tv->vval.v_dict == get_globvar_dict() ! || lp->ll_tv->vval.v_dict == ! &SCRIPT_ITEM(current_sctx.sc_sid)->sn_vars->sv_dict) ! && (rettv->v_type == VAR_FUNC ! || rettv->v_type == VAR_PARTIAL) ! && var_wrong_func_name(lp->ll_newkey, TRUE)) return; // Need to add an item to the Dictionary. --- 1462,1469 ---- semsg(_(e_dictkey), lp->ll_newkey); return; } ! if (dict_wrong_func_name(lp->ll_tv->vval.v_dict, rettv, ! lp->ll_newkey)) return; // Need to add an item to the Dictionary. *** ../vim-8.2.2919/src/dict.c 2021-02-11 21:19:30.522147936 +0100 --- src/dict.c 2021-06-01 21:20:19.846719776 +0200 *************** *** 345,356 **** --- 345,372 ---- } /* + * Check for adding a function to g: or s:. + * If the name is wrong give an error message and return TRUE. + */ + int + dict_wrong_func_name(dict_T *d, typval_T *tv, char_u *name) + { + return (d == get_globvar_dict() + || (SCRIPT_ID_VALID(current_sctx.sc_sid) + && d == &SCRIPT_ITEM(current_sctx.sc_sid)->sn_vars->sv_dict)) + && (tv->v_type == VAR_FUNC || tv->v_type == VAR_PARTIAL) + && var_wrong_func_name(name, TRUE); + } + + /* * Add item "item" to Dictionary "d". * Returns FAIL when out of memory and when key already exists. */ int dict_add(dict_T *d, dictitem_T *item) { + if (dict_wrong_func_name(d, &item->di_tv, item->di_key)) + return FAIL; return hash_add(&d->dv_hashtab, item->di_key); } *************** *** 1109,1114 **** --- 1125,1132 ---- if (value_check_lock(di1->di_tv.v_lock, arg_errmsg, TRUE) || var_check_ro(di1->di_flags, arg_errmsg, TRUE)) break; + if (dict_wrong_func_name(d1, &HI2DI(hi2)->di_tv, hi2->hi_key)) + break; clear_tv(&di1->di_tv); copy_tv(&HI2DI(hi2)->di_tv, &di1->di_tv); } *** ../vim-8.2.2919/src/proto/dict.pro 2020-12-04 19:11:53.877306973 +0100 --- src/proto/dict.pro 2021-06-01 21:11:22.828004704 +0200 *************** *** 13,18 **** --- 13,19 ---- void dictitem_remove(dict_T *dict, dictitem_T *item); void dictitem_free(dictitem_T *item); dict_T *dict_copy(dict_T *orig, int deep, int copyID); + int dict_wrong_func_name(dict_T *d, typval_T *tv, char_u *name); int dict_add(dict_T *d, dictitem_T *item); int dict_add_number(dict_T *d, char *key, varnumber_T nr); int dict_add_bool(dict_T *d, char *key, varnumber_T nr); *** ../vim-8.2.2919/src/testdir/test_functions.vim 2021-05-31 22:15:22.130559993 +0200 --- src/testdir/test_functions.vim 2021-06-01 21:17:08.803176643 +0200 *************** *** 2686,2691 **** --- 2686,2696 ---- call assert_fails('let g:.trim = {x -> " " .. x}', 'E704:') call assert_fails('let s:["trim"] = {x -> " " .. x}', 'E704:') call assert_fails('let s:.trim = {x -> " " .. x}', 'E704:') + + call assert_fails('call extend(g:, #{foo: { -> "foo" }})', 'E704:') + let g:bar = 123 + call extend(g:, #{bar: { -> "foo" }}, "keep") + call assert_fails('call extend(g:, #{bar: { -> "foo" }}, "force")', 'E704:') endfunc *** ../vim-8.2.2919/src/version.c 2021-06-01 20:48:35.283404265 +0200 --- src/version.c 2021-06-01 21:21:10.470599388 +0200 *************** *** 752,753 **** --- 752,755 ---- { /* Add new patch number below this line */ + /**/ + 2920, /**/ -- Sorry, no fortune today. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///