]> granicus.if.org Git - vim/commitdiff
patch 8.2.2920: still a way to shadow a builtin function v8.2.2920
authorBram Moolenaar <Bram@vim.org>
Tue, 1 Jun 2021 19:21:55 +0000 (21:21 +0200)
committerBram Moolenaar <Bram@vim.org>
Tue, 1 Jun 2021 19:21:55 +0000 (21:21 +0200)
Problem:    Still a way to shadow a builtin function. (Yasuhiro Matsumoto)
Solution:   Check the key when using extend(). (issue #8302)

src/dict.c
src/eval.c
src/proto/dict.pro
src/testdir/test_functions.vim
src/version.c

index 922da473ced7bd738b8e152306edfcd609b7db23..876eeea4928cb3b3e2a21ebca40fc3cc6c91c6a8 100644 (file)
@@ -344,6 +344,20 @@ dict_copy(dict_T *orig, int deep, int copyID)
     return copy;
 }
 
+/*
+ * 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.
@@ -351,6 +365,8 @@ dict_copy(dict_T *orig, int deep, int copyID)
     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,6 +1125,8 @@ dict_extend(dict_T *d1, dict_T *d2, char_u *action)
                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);
            }
index 9fb3b4e2ca69f85e333d6cfadddbc3ae45b394e6..7a05d359bac4516ad00ede475e8079b65ce300f4 100644 (file)
@@ -1462,12 +1462,8 @@ set_var_lval(
                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))
+           if (dict_wrong_func_name(lp->ll_tv->vval.v_dict, rettv,
+                                                               lp->ll_newkey))
                return;
 
            // Need to add an item to the Dictionary.
index dbfdcdcbbd94f1eec3b6008b5acc65c858197889..7789d4c6caf1fa33ed075ba3c9571b1df235b453 100644 (file)
@@ -13,6 +13,7 @@ dictitem_T *dictitem_alloc(char_u *key);
 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);
index e1aff6137d25dcbda6b42371593a6660f54447b7..f945e9064e9d6e3887a0a69df8cc4086e8205ffb 100644 (file)
@@ -2686,6 +2686,11 @@ func Test_builtin_check()
   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
 
 
index a9a7b29f51a57f98f31ff3118371dddbbd4ca333..1c01adb222f4038503e157735e2b073a921d99fc 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    2920,
 /**/
     2919,
 /**/