mirror of
https://github.com/neovim/neovim.git
synced 2025-09-12 22:38:16 +00:00
vim-patch:8.1.0897: can modify a:000 when using a reference (#14902)
Problem: Can modify a:000 when using a reference.
Solution: Make check for locked variable stricter. (Ozaki Kiichi,
closes vim/vim#3930)
05c00c038b
This commit is contained in:
@@ -2340,10 +2340,8 @@ static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv,
|
|||||||
if (get_var_tv((const char *)lp->ll_name, (int)STRLEN(lp->ll_name),
|
if (get_var_tv((const char *)lp->ll_name, (int)STRLEN(lp->ll_name),
|
||||||
&tv, &di, true, false) == OK) {
|
&tv, &di, true, false) == OK) {
|
||||||
if ((di == NULL
|
if ((di == NULL
|
||||||
|| (!var_check_ro(di->di_flags, (const char *)lp->ll_name,
|
|| (!var_check_ro(di->di_flags, lp->ll_name, TV_CSTRING)
|
||||||
TV_CSTRING)
|
&& !tv_check_lock(&di->di_tv, lp->ll_name, TV_CSTRING)))
|
||||||
&& !tv_check_lock(di->di_tv.v_lock, (const char *)lp->ll_name,
|
|
||||||
TV_CSTRING)))
|
|
||||||
&& eexe_mod_op(&tv, rettv, op) == OK) {
|
&& eexe_mod_op(&tv, rettv, op) == OK) {
|
||||||
set_var(lp->ll_name, lp->ll_name_len, &tv, false);
|
set_var(lp->ll_name, lp->ll_name_len, &tv, false);
|
||||||
}
|
}
|
||||||
@@ -2353,10 +2351,10 @@ static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv,
|
|||||||
set_var_const(lp->ll_name, lp->ll_name_len, rettv, copy, is_const);
|
set_var_const(lp->ll_name, lp->ll_name_len, rettv, copy, is_const);
|
||||||
}
|
}
|
||||||
*endp = cc;
|
*endp = cc;
|
||||||
} else if (tv_check_lock(lp->ll_newkey == NULL
|
} else if (var_check_lock(lp->ll_newkey == NULL
|
||||||
? lp->ll_tv->v_lock
|
? lp->ll_tv->v_lock
|
||||||
: lp->ll_tv->vval.v_dict->dv_lock,
|
: lp->ll_tv->vval.v_dict->dv_lock,
|
||||||
(const char *)lp->ll_name, TV_CSTRING)) {
|
lp->ll_name, TV_CSTRING)) {
|
||||||
} else if (lp->ll_range) {
|
} else if (lp->ll_range) {
|
||||||
listitem_T *ll_li = lp->ll_li;
|
listitem_T *ll_li = lp->ll_li;
|
||||||
int ll_n1 = lp->ll_n1;
|
int ll_n1 = lp->ll_n1;
|
||||||
@@ -2369,9 +2367,8 @@ static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv,
|
|||||||
// Check whether any of the list items is locked
|
// Check whether any of the list items is locked
|
||||||
for (ri = tv_list_first(rettv->vval.v_list);
|
for (ri = tv_list_first(rettv->vval.v_list);
|
||||||
ri != NULL && ll_li != NULL; ) {
|
ri != NULL && ll_li != NULL; ) {
|
||||||
if (tv_check_lock(TV_LIST_ITEM_TV(ll_li)->v_lock,
|
if (var_check_lock(TV_LIST_ITEM_TV(ll_li)->v_lock, lp->ll_name,
|
||||||
(const char *)lp->ll_name,
|
TV_CSTRING)) {
|
||||||
TV_CSTRING)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ri = TV_LIST_ITEM_NEXT(rettv->vval.v_list, ri);
|
ri = TV_LIST_ITEM_NEXT(rettv->vval.v_list, ri);
|
||||||
@@ -2795,13 +2792,13 @@ static int do_unlet_var(lval_T *lp, char_u *name_end, exarg_T *eap,
|
|||||||
} else if ((lp->ll_list != NULL
|
} else if ((lp->ll_list != NULL
|
||||||
// ll_list is not NULL when lvalue is not in a list, NULL lists
|
// ll_list is not NULL when lvalue is not in a list, NULL lists
|
||||||
// yield E689.
|
// yield E689.
|
||||||
&& tv_check_lock(tv_list_locked(lp->ll_list),
|
&& var_check_lock(tv_list_locked(lp->ll_list),
|
||||||
(const char *)lp->ll_name,
|
lp->ll_name,
|
||||||
lp->ll_name_len))
|
lp->ll_name_len))
|
||||||
|| (lp->ll_dict != NULL
|
|| (lp->ll_dict != NULL
|
||||||
&& tv_check_lock(lp->ll_dict->dv_lock,
|
&& var_check_lock(lp->ll_dict->dv_lock,
|
||||||
(const char *)lp->ll_name,
|
lp->ll_name,
|
||||||
lp->ll_name_len))) {
|
lp->ll_name_len))) {
|
||||||
return FAIL;
|
return FAIL;
|
||||||
} else if (lp->ll_range) {
|
} else if (lp->ll_range) {
|
||||||
assert(lp->ll_list != NULL);
|
assert(lp->ll_list != NULL);
|
||||||
@@ -2810,9 +2807,9 @@ static int do_unlet_var(lval_T *lp, char_u *name_end, exarg_T *eap,
|
|||||||
listitem_T *last_li = first_li;
|
listitem_T *last_li = first_li;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
listitem_T *const li = TV_LIST_ITEM_NEXT(lp->ll_list, lp->ll_li);
|
listitem_T *const li = TV_LIST_ITEM_NEXT(lp->ll_list, lp->ll_li);
|
||||||
if (tv_check_lock(TV_LIST_ITEM_TV(lp->ll_li)->v_lock,
|
if (var_check_lock(TV_LIST_ITEM_TV(lp->ll_li)->v_lock,
|
||||||
(const char *)lp->ll_name,
|
lp->ll_name,
|
||||||
lp->ll_name_len)) {
|
lp->ll_name_len)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
lp->ll_li = li;
|
lp->ll_li = li;
|
||||||
@@ -2897,11 +2894,11 @@ int do_unlet(const char *const name, const size_t name_len, const bool forceit)
|
|||||||
dictitem_T *const di = TV_DICT_HI2DI(hi);
|
dictitem_T *const di = TV_DICT_HI2DI(hi);
|
||||||
if (var_check_fixed(di->di_flags, (const char *)name, TV_CSTRING)
|
if (var_check_fixed(di->di_flags, (const char *)name, TV_CSTRING)
|
||||||
|| var_check_ro(di->di_flags, (const char *)name, TV_CSTRING)
|
|| var_check_ro(di->di_flags, (const char *)name, TV_CSTRING)
|
||||||
|| tv_check_lock(d->dv_lock, (const char *)name, TV_CSTRING)) {
|
|| var_check_lock(d->dv_lock, name, TV_CSTRING)) {
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tv_check_lock(d->dv_lock, (const char *)name, TV_CSTRING)) {
|
if (var_check_lock(d->dv_lock, name, TV_CSTRING)) {
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5962,14 +5959,14 @@ void filter_map(typval_T *argvars, typval_T *rettv, int map)
|
|||||||
if (argvars[0].v_type == VAR_LIST) {
|
if (argvars[0].v_type == VAR_LIST) {
|
||||||
tv_copy(&argvars[0], rettv);
|
tv_copy(&argvars[0], rettv);
|
||||||
if ((l = argvars[0].vval.v_list) == NULL
|
if ((l = argvars[0].vval.v_list) == NULL
|
||||||
|| (!map && tv_check_lock(tv_list_locked(l), arg_errmsg,
|
|| (!map
|
||||||
TV_TRANSLATE))) {
|
&& var_check_lock(tv_list_locked(l), arg_errmsg, TV_TRANSLATE))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (argvars[0].v_type == VAR_DICT) {
|
} else if (argvars[0].v_type == VAR_DICT) {
|
||||||
tv_copy(&argvars[0], rettv);
|
tv_copy(&argvars[0], rettv);
|
||||||
if ((d = argvars[0].vval.v_dict) == NULL
|
if ((d = argvars[0].vval.v_dict) == NULL
|
||||||
|| (!map && tv_check_lock(d->dv_lock, arg_errmsg, TV_TRANSLATE))) {
|
|| (!map && var_check_lock(d->dv_lock, arg_errmsg, TV_TRANSLATE))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -6002,7 +5999,7 @@ void filter_map(typval_T *argvars, typval_T *rettv, int map)
|
|||||||
|
|
||||||
di = TV_DICT_HI2DI(hi);
|
di = TV_DICT_HI2DI(hi);
|
||||||
if (map
|
if (map
|
||||||
&& (tv_check_lock(di->di_tv.v_lock, arg_errmsg, TV_TRANSLATE)
|
&& (var_check_lock(di->di_tv.v_lock, arg_errmsg, TV_TRANSLATE)
|
||||||
|| var_check_ro(di->di_flags, arg_errmsg, TV_TRANSLATE))) {
|
|| var_check_ro(di->di_flags, arg_errmsg, TV_TRANSLATE))) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -6029,8 +6026,8 @@ void filter_map(typval_T *argvars, typval_T *rettv, int map)
|
|||||||
|
|
||||||
for (listitem_T *li = tv_list_first(l); li != NULL;) {
|
for (listitem_T *li = tv_list_first(l); li != NULL;) {
|
||||||
if (map
|
if (map
|
||||||
&& tv_check_lock(TV_LIST_ITEM_TV(li)->v_lock, arg_errmsg,
|
&& var_check_lock(TV_LIST_ITEM_TV(li)->v_lock, arg_errmsg,
|
||||||
TV_TRANSLATE)) {
|
TV_TRANSLATE)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
vimvars[VV_KEY].vv_nr = idx;
|
vimvars[VV_KEY].vv_nr = idx;
|
||||||
@@ -8947,7 +8944,7 @@ static void set_var_const(const char *name, const size_t name_len,
|
|||||||
|
|
||||||
// existing variable, need to clear the value
|
// existing variable, need to clear the value
|
||||||
if (var_check_ro(v->di_flags, name, name_len)
|
if (var_check_ro(v->di_flags, name, name_len)
|
||||||
|| tv_check_lock(v->di_tv.v_lock, name, name_len)) {
|
|| var_check_lock(v->di_tv.v_lock, name, name_len)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -268,7 +268,8 @@ static void f_add(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
rettv->vval.v_number = 1; // Default: failed.
|
rettv->vval.v_number = 1; // Default: failed.
|
||||||
if (argvars[0].v_type == VAR_LIST) {
|
if (argvars[0].v_type == VAR_LIST) {
|
||||||
list_T *const l = argvars[0].vval.v_list;
|
list_T *const l = argvars[0].vval.v_list;
|
||||||
if (!tv_check_lock(tv_list_locked(l), N_("add() argument"), TV_TRANSLATE)) {
|
if (!var_check_lock(tv_list_locked(l), N_("add() argument"),
|
||||||
|
TV_TRANSLATE)) {
|
||||||
tv_list_append_tv(l, &argvars[1]);
|
tv_list_append_tv(l, &argvars[1]);
|
||||||
tv_copy(&argvars[0], rettv);
|
tv_copy(&argvars[0], rettv);
|
||||||
}
|
}
|
||||||
@@ -2277,9 +2278,9 @@ static void f_flatten(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
|
|
||||||
list = argvars[0].vval.v_list;
|
list = argvars[0].vval.v_list;
|
||||||
if (list != NULL
|
if (list != NULL
|
||||||
&& !tv_check_lock(tv_list_locked(list),
|
&& !var_check_lock(tv_list_locked(list),
|
||||||
N_("flatten() argument"),
|
N_("flatten() argument"),
|
||||||
TV_TRANSLATE)
|
TV_TRANSLATE)
|
||||||
&& tv_list_flatten(list, maxdepth) == OK) {
|
&& tv_list_flatten(list, maxdepth) == OK) {
|
||||||
tv_copy(&argvars[0], rettv);
|
tv_copy(&argvars[0], rettv);
|
||||||
}
|
}
|
||||||
@@ -2299,7 +2300,7 @@ static void f_extend(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
|
|
||||||
list_T *const l1 = argvars[0].vval.v_list;
|
list_T *const l1 = argvars[0].vval.v_list;
|
||||||
list_T *const l2 = argvars[1].vval.v_list;
|
list_T *const l2 = argvars[1].vval.v_list;
|
||||||
if (!tv_check_lock(tv_list_locked(l1), arg_errmsg, TV_TRANSLATE)) {
|
if (!var_check_lock(tv_list_locked(l1), arg_errmsg, TV_TRANSLATE)) {
|
||||||
listitem_T *item;
|
listitem_T *item;
|
||||||
if (argvars[2].v_type != VAR_UNKNOWN) {
|
if (argvars[2].v_type != VAR_UNKNOWN) {
|
||||||
before = (long)tv_get_number_chk(&argvars[2], &error);
|
before = (long)tv_get_number_chk(&argvars[2], &error);
|
||||||
@@ -2328,13 +2329,13 @@ static void f_extend(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
dict_T *const d1 = argvars[0].vval.v_dict;
|
dict_T *const d1 = argvars[0].vval.v_dict;
|
||||||
dict_T *const d2 = argvars[1].vval.v_dict;
|
dict_T *const d2 = argvars[1].vval.v_dict;
|
||||||
if (d1 == NULL) {
|
if (d1 == NULL) {
|
||||||
const bool locked = tv_check_lock(VAR_FIXED, arg_errmsg, TV_TRANSLATE);
|
const bool locked = var_check_lock(VAR_FIXED, arg_errmsg, TV_TRANSLATE);
|
||||||
(void)locked;
|
(void)locked;
|
||||||
assert(locked == true);
|
assert(locked == true);
|
||||||
} else if (d2 == NULL) {
|
} else if (d2 == NULL) {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
tv_copy(&argvars[0], rettv);
|
tv_copy(&argvars[0], rettv);
|
||||||
} else if (!tv_check_lock(d1->dv_lock, arg_errmsg, TV_TRANSLATE)) {
|
} else if (!var_check_lock(d1->dv_lock, arg_errmsg, TV_TRANSLATE)) {
|
||||||
const char *action = "force";
|
const char *action = "force";
|
||||||
// Check the third argument.
|
// Check the third argument.
|
||||||
if (argvars[2].v_type != VAR_UNKNOWN) {
|
if (argvars[2].v_type != VAR_UNKNOWN) {
|
||||||
@@ -4845,8 +4846,8 @@ static void f_insert(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
|
|
||||||
if (argvars[0].v_type != VAR_LIST) {
|
if (argvars[0].v_type != VAR_LIST) {
|
||||||
EMSG2(_(e_listarg), "insert()");
|
EMSG2(_(e_listarg), "insert()");
|
||||||
} else if (!tv_check_lock(tv_list_locked((l = argvars[0].vval.v_list)),
|
} else if (!var_check_lock(tv_list_locked((l = argvars[0].vval.v_list)),
|
||||||
N_("insert() argument"), TV_TRANSLATE)) {
|
N_("insert() argument"), TV_TRANSLATE)) {
|
||||||
long before = 0;
|
long before = 0;
|
||||||
if (argvars[2].v_type != VAR_UNKNOWN) {
|
if (argvars[2].v_type != VAR_UNKNOWN) {
|
||||||
before = tv_get_number_chk(&argvars[2], &error);
|
before = tv_get_number_chk(&argvars[2], &error);
|
||||||
@@ -7079,7 +7080,7 @@ static void f_remove(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
if (argvars[2].v_type != VAR_UNKNOWN) {
|
if (argvars[2].v_type != VAR_UNKNOWN) {
|
||||||
EMSG2(_(e_toomanyarg), "remove()");
|
EMSG2(_(e_toomanyarg), "remove()");
|
||||||
} else if ((d = argvars[0].vval.v_dict) != NULL
|
} else if ((d = argvars[0].vval.v_dict) != NULL
|
||||||
&& !tv_check_lock(d->dv_lock, arg_errmsg, TV_TRANSLATE)) {
|
&& !var_check_lock(d->dv_lock, arg_errmsg, TV_TRANSLATE)) {
|
||||||
const char *key = tv_get_string_chk(&argvars[1]);
|
const char *key = tv_get_string_chk(&argvars[1]);
|
||||||
if (key != NULL) {
|
if (key != NULL) {
|
||||||
di = tv_dict_find(d, key, -1);
|
di = tv_dict_find(d, key, -1);
|
||||||
@@ -7098,8 +7099,8 @@ static void f_remove(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
}
|
}
|
||||||
} else if (argvars[0].v_type != VAR_LIST) {
|
} else if (argvars[0].v_type != VAR_LIST) {
|
||||||
EMSG2(_(e_listdictarg), "remove()");
|
EMSG2(_(e_listdictarg), "remove()");
|
||||||
} else if (!tv_check_lock(tv_list_locked((l = argvars[0].vval.v_list)),
|
} else if (!var_check_lock(tv_list_locked((l = argvars[0].vval.v_list)),
|
||||||
arg_errmsg, TV_TRANSLATE)) {
|
arg_errmsg, TV_TRANSLATE)) {
|
||||||
bool error = false;
|
bool error = false;
|
||||||
|
|
||||||
idx = tv_get_number_chk(&argvars[1], &error);
|
idx = tv_get_number_chk(&argvars[1], &error);
|
||||||
@@ -7374,8 +7375,8 @@ static void f_reverse(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
list_T *l;
|
list_T *l;
|
||||||
if (argvars[0].v_type != VAR_LIST) {
|
if (argvars[0].v_type != VAR_LIST) {
|
||||||
EMSG2(_(e_listarg), "reverse()");
|
EMSG2(_(e_listarg), "reverse()");
|
||||||
} else if (!tv_check_lock(tv_list_locked((l = argvars[0].vval.v_list)),
|
} else if (!var_check_lock(tv_list_locked((l = argvars[0].vval.v_list)),
|
||||||
N_("reverse() argument"), TV_TRANSLATE)) {
|
N_("reverse() argument"), TV_TRANSLATE)) {
|
||||||
tv_list_reverse(l);
|
tv_list_reverse(l);
|
||||||
tv_list_set_ret(rettv, l);
|
tv_list_set_ret(rettv, l);
|
||||||
}
|
}
|
||||||
@@ -9462,7 +9463,7 @@ static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort)
|
|||||||
EMSG2(_(e_listarg), sort ? "sort()" : "uniq()");
|
EMSG2(_(e_listarg), sort ? "sort()" : "uniq()");
|
||||||
} else {
|
} else {
|
||||||
list_T *const l = argvars[0].vval.v_list;
|
list_T *const l = argvars[0].vval.v_list;
|
||||||
if (tv_check_lock(tv_list_locked(l), arg_errmsg, TV_TRANSLATE)) {
|
if (var_check_lock(tv_list_locked(l), arg_errmsg, TV_TRANSLATE)) {
|
||||||
goto theend;
|
goto theend;
|
||||||
}
|
}
|
||||||
tv_list_set_ret(rettv, l);
|
tv_list_set_ret(rettv, l);
|
||||||
|
@@ -1994,7 +1994,7 @@ void tv_dict_extend(dict_T *const d1, dict_T *const d2,
|
|||||||
} else if (*action == 'f' && di2 != di1) {
|
} else if (*action == 'f' && di2 != di1) {
|
||||||
typval_T oldtv;
|
typval_T oldtv;
|
||||||
|
|
||||||
if (tv_check_lock(di1->di_tv.v_lock, arg_errmsg, arg_errmsg_len)
|
if (var_check_lock(di1->di_tv.v_lock, arg_errmsg, arg_errmsg_len)
|
||||||
|| var_check_ro(di1->di_flags, arg_errmsg, arg_errmsg_len)) {
|
|| var_check_ro(di1->di_flags, arg_errmsg, arg_errmsg_len)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2625,7 +2625,7 @@ bool tv_islocked(const typval_T *const tv)
|
|||||||
///
|
///
|
||||||
/// Also gives an error message when typval is locked.
|
/// Also gives an error message when typval is locked.
|
||||||
///
|
///
|
||||||
/// @param[in] lock Lock status.
|
/// @param[in] tv Typval.
|
||||||
/// @param[in] name Variable name, used in the error message.
|
/// @param[in] name Variable name, used in the error message.
|
||||||
/// @param[in] name_len Variable name length. Use #TV_TRANSLATE to translate
|
/// @param[in] name_len Variable name length. Use #TV_TRANSLATE to translate
|
||||||
/// variable name and compute the length. Use #TV_CSTRING
|
/// variable name and compute the length. Use #TV_CSTRING
|
||||||
@@ -2639,9 +2639,36 @@ bool tv_islocked(const typval_T *const tv)
|
|||||||
/// gettext.
|
/// gettext.
|
||||||
///
|
///
|
||||||
/// @return true if variable is locked, false otherwise.
|
/// @return true if variable is locked, false otherwise.
|
||||||
bool tv_check_lock(const VarLockStatus lock, const char *name,
|
bool tv_check_lock(const typval_T *tv, const char *name,
|
||||||
size_t name_len)
|
size_t name_len)
|
||||||
FUNC_ATTR_WARN_UNUSED_RESULT
|
FUNC_ATTR_WARN_UNUSED_RESULT
|
||||||
|
{
|
||||||
|
VarLockStatus lock = VAR_UNLOCKED;
|
||||||
|
|
||||||
|
switch (tv->v_type) {
|
||||||
|
// case VAR_BLOB:
|
||||||
|
// if (tv->vval.v_blob != NULL)
|
||||||
|
// lock = tv->vval.v_blob->bv_lock;
|
||||||
|
// break;
|
||||||
|
case VAR_LIST:
|
||||||
|
if (tv->vval.v_list != NULL) {
|
||||||
|
lock = tv->vval.v_list->lv_lock;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case VAR_DICT:
|
||||||
|
if (tv->vval.v_dict != NULL) {
|
||||||
|
lock = tv->vval.v_dict->dv_lock;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return var_check_lock(tv->v_lock, name, name_len)
|
||||||
|
|| (lock != VAR_UNLOCKED && var_check_lock(lock, name, name_len));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @return true if variable "name" is locked (immutable)
|
||||||
|
bool var_check_lock(VarLockStatus lock, const char *name, size_t name_len)
|
||||||
{
|
{
|
||||||
const char *error_message = NULL;
|
const char *error_message = NULL;
|
||||||
switch (lock) {
|
switch (lock) {
|
||||||
|
@@ -2455,13 +2455,13 @@ void ex_function(exarg_T *eap)
|
|||||||
goto erret;
|
goto erret;
|
||||||
}
|
}
|
||||||
if (fudi.fd_di == NULL) {
|
if (fudi.fd_di == NULL) {
|
||||||
if (tv_check_lock(fudi.fd_dict->dv_lock, (const char *)eap->arg,
|
if (var_check_lock(fudi.fd_dict->dv_lock, (const char *)eap->arg,
|
||||||
TV_CSTRING)) {
|
TV_CSTRING)) {
|
||||||
// Can't add a function to a locked dictionary
|
// Can't add a function to a locked dictionary
|
||||||
goto erret;
|
goto erret;
|
||||||
}
|
}
|
||||||
} else if (tv_check_lock(fudi.fd_di->di_tv.v_lock, (const char *)eap->arg,
|
} else if (var_check_lock(fudi.fd_di->di_tv.v_lock, (const char *)eap->arg,
|
||||||
TV_CSTRING)) {
|
TV_CSTRING)) {
|
||||||
// Can't change an existing function if it is locked
|
// Can't change an existing function if it is locked
|
||||||
goto erret;
|
goto erret;
|
||||||
}
|
}
|
||||||
|
@@ -126,10 +126,15 @@ endfunction
|
|||||||
|
|
||||||
func s:set_varg7(...) abort
|
func s:set_varg7(...) abort
|
||||||
let b = a:000
|
let b = a:000
|
||||||
call add(b, 1)
|
let b += [1]
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
func s:set_varg8(...) abort
|
func s:set_varg8(...) abort
|
||||||
|
let b = a:000
|
||||||
|
call add(b, 1)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
func s:set_varg9(...) abort
|
||||||
let b = a:000
|
let b = a:000
|
||||||
let b[0][0] = 1
|
let b[0][0] = 1
|
||||||
endfunction
|
endfunction
|
||||||
@@ -142,7 +147,8 @@ func Test_let_varg_fail()
|
|||||||
call s:set_varg5([0])
|
call s:set_varg5([0])
|
||||||
call assert_fails('call s:set_varg6(1)', 'E742:')
|
call assert_fails('call s:set_varg6(1)', 'E742:')
|
||||||
call assert_fails('call s:set_varg7(1)', 'E742:')
|
call assert_fails('call s:set_varg7(1)', 'E742:')
|
||||||
call s:set_varg8([0])
|
call assert_fails('call s:set_varg8(1)', 'E742:')
|
||||||
|
call s:set_varg9([0])
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
func Test_let_utf8_environment()
|
func Test_let_utf8_environment()
|
||||||
|
@@ -2623,7 +2623,7 @@ describe('typval.c', function()
|
|||||||
describe('check_lock()', function()
|
describe('check_lock()', function()
|
||||||
local function tv_check_lock(lock, name, name_len, emsg)
|
local function tv_check_lock(lock, name, name_len, emsg)
|
||||||
return check_emsg(function()
|
return check_emsg(function()
|
||||||
return lib.tv_check_lock(lock, name, name_len)
|
return lib.var_check_lock(lock, name, name_len)
|
||||||
end, emsg)
|
end, emsg)
|
||||||
end
|
end
|
||||||
itp('works', function()
|
itp('works', function()
|
||||||
|
Reference in New Issue
Block a user