mirror of
https://github.com/neovim/neovim.git
synced 2024-12-24 21:25:04 -07:00
vim-patch:7.4.717
Problem: ":let list += list" can change a locked list.
Solution: Check for the lock earlier. (Olaf Dabrunz)
1cd5e613b0
This commit is contained in:
parent
fef753fa6d
commit
70ab198221
@ -1700,12 +1700,13 @@ static char_u *list_arg_vars(exarg_T *eap, char_u *arg, int *first)
|
|||||||
}
|
}
|
||||||
error = TRUE;
|
error = TRUE;
|
||||||
} else {
|
} else {
|
||||||
if (tofree != NULL)
|
if (tofree != NULL) {
|
||||||
name = tofree;
|
name = tofree;
|
||||||
if (get_var_tv(name, len, &tv, TRUE, FALSE) == FAIL)
|
}
|
||||||
error = TRUE;
|
if (get_var_tv(name, len, &tv, NULL, true, false) == FAIL) {
|
||||||
else {
|
error = true;
|
||||||
/* handle d.key, l[idx], f(expr) */
|
} else {
|
||||||
|
// handle d.key, l[idx], f(expr)
|
||||||
arg_subsc = arg;
|
arg_subsc = arg;
|
||||||
if (handle_subscript(&arg, &tv, TRUE, TRUE) == FAIL)
|
if (handle_subscript(&arg, &tv, TRUE, TRUE) == FAIL)
|
||||||
error = TRUE;
|
error = TRUE;
|
||||||
@ -2274,11 +2275,16 @@ static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, int copy, ch
|
|||||||
if (op != NULL && *op != '=') {
|
if (op != NULL && *op != '=') {
|
||||||
typval_T tv;
|
typval_T tv;
|
||||||
|
|
||||||
/* handle +=, -= and .= */
|
// handle +=, -= and .=
|
||||||
|
di = NULL;
|
||||||
if (get_var_tv(lp->ll_name, (int)STRLEN(lp->ll_name),
|
if (get_var_tv(lp->ll_name, (int)STRLEN(lp->ll_name),
|
||||||
&tv, TRUE, FALSE) == OK) {
|
&tv, &di, true, false) == OK) {
|
||||||
if (tv_op(&tv, rettv, op) == OK)
|
if ((di == NULL
|
||||||
set_var(lp->ll_name, &tv, FALSE);
|
|| (!var_check_ro(di->di_flags, lp->ll_name, false) &&
|
||||||
|
!tv_check_lock(di->di_tv.v_lock, lp->ll_name, false)))
|
||||||
|
&& tv_op(&tv, rettv, op) == OK) {
|
||||||
|
set_var(lp->ll_name, &tv, false);
|
||||||
|
}
|
||||||
clear_tv(&tv);
|
clear_tv(&tv);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
@ -4240,7 +4246,7 @@ static int eval7(
|
|||||||
ret = FAIL;
|
ret = FAIL;
|
||||||
}
|
}
|
||||||
} else if (evaluate) {
|
} else if (evaluate) {
|
||||||
ret = get_var_tv(s, len, rettv, true, false);
|
ret = get_var_tv(s, len, rettv, NULL, true, false);
|
||||||
} else {
|
} else {
|
||||||
ret = OK;
|
ret = OK;
|
||||||
}
|
}
|
||||||
@ -9132,9 +9138,10 @@ static void f_exists(typval_T *argvars, typval_T *rettv)
|
|||||||
name = p;
|
name = p;
|
||||||
len = get_name_len(&p, &tofree, TRUE, FALSE);
|
len = get_name_len(&p, &tofree, TRUE, FALSE);
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
if (tofree != NULL)
|
if (tofree != NULL) {
|
||||||
name = tofree;
|
name = tofree;
|
||||||
n = (get_var_tv(name, len, &tv, FALSE, TRUE) == OK);
|
}
|
||||||
|
n = (get_var_tv(name, len, &tv, NULL, false, true) == OK);
|
||||||
if (n) {
|
if (n) {
|
||||||
/* handle d.key, l[idx], f(expr) */
|
/* handle d.key, l[idx], f(expr) */
|
||||||
n = (handle_subscript(&p, &tv, TRUE, FALSE) == OK);
|
n = (handle_subscript(&p, &tv, TRUE, FALSE) == OK);
|
||||||
@ -18166,10 +18173,11 @@ char_u *set_cmdarg(exarg_T *eap, char_u *oldarg)
|
|||||||
static int
|
static int
|
||||||
get_var_tv (
|
get_var_tv (
|
||||||
char_u *name,
|
char_u *name,
|
||||||
int len, /* length of "name" */
|
int len, // length of "name"
|
||||||
typval_T *rettv, /* NULL when only checking existence */
|
typval_T *rettv, // NULL when only checking existence
|
||||||
int verbose, /* may give error message */
|
dictitem_T **dip, // non-NULL when typval's dict item is needed
|
||||||
int no_autoload /* do not use script autoloading */
|
int verbose, // may give error message
|
||||||
|
int no_autoload // do not use script autoloading
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
int ret = OK;
|
int ret = OK;
|
||||||
@ -18195,8 +18203,12 @@ get_var_tv (
|
|||||||
*/
|
*/
|
||||||
else {
|
else {
|
||||||
v = find_var(name, NULL, no_autoload);
|
v = find_var(name, NULL, no_autoload);
|
||||||
if (v != NULL)
|
if (v != NULL) {
|
||||||
tv = &v->di_tv;
|
tv = &v->di_tv;
|
||||||
|
if (dip != NULL) {
|
||||||
|
*dip = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tv == NULL) {
|
if (tv == NULL) {
|
||||||
@ -18878,10 +18890,8 @@ set_var (
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Handle setting internal v: variables separately where needed to
|
||||||
* Handle setting internal v: variables separately: we don't change
|
// prevent changing the type.
|
||||||
* the type.
|
|
||||||
*/
|
|
||||||
if (ht == &vimvarht) {
|
if (ht == &vimvarht) {
|
||||||
if (v->di_tv.v_type == VAR_STRING) {
|
if (v->di_tv.v_type == VAR_STRING) {
|
||||||
xfree(v->di_tv.vval.v_string);
|
xfree(v->di_tv.vval.v_string);
|
||||||
@ -18892,9 +18902,8 @@ set_var (
|
|||||||
v->di_tv.vval.v_string = tv->vval.v_string;
|
v->di_tv.vval.v_string = tv->vval.v_string;
|
||||||
tv->vval.v_string = NULL;
|
tv->vval.v_string = NULL;
|
||||||
}
|
}
|
||||||
} else if (v->di_tv.v_type != VAR_NUMBER)
|
return;
|
||||||
EMSG2(_(e_intern2), "set_var()");
|
} else if (v->di_tv.v_type == VAR_NUMBER) {
|
||||||
else {
|
|
||||||
v->di_tv.vval.v_number = get_tv_number(tv);
|
v->di_tv.vval.v_number = get_tv_number(tv);
|
||||||
if (STRCMP(varname, "searchforward") == 0)
|
if (STRCMP(varname, "searchforward") == 0)
|
||||||
set_search_direction(v->di_tv.vval.v_number ? '/' : '?');
|
set_search_direction(v->di_tv.vval.v_number ? '/' : '?');
|
||||||
@ -18902,8 +18911,10 @@ set_var (
|
|||||||
no_hlsearch = !v->di_tv.vval.v_number;
|
no_hlsearch = !v->di_tv.vval.v_number;
|
||||||
redraw_all_later(SOME_VALID);
|
redraw_all_later(SOME_VALID);
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
|
} else if (v->di_tv.v_type != tv->v_type) {
|
||||||
|
EMSG2(_(e_intern2), "set_var()");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (watched) {
|
if (watched) {
|
||||||
|
@ -442,6 +442,17 @@ let l = [0, 1, 2, 3]
|
|||||||
:unlockvar 1 b:
|
:unlockvar 1 b:
|
||||||
:unlet! b:testvar
|
:unlet! b:testvar
|
||||||
:"
|
:"
|
||||||
|
:$put ='No :let += of locked list variable:'
|
||||||
|
:let l = ['a', 'b', 3]
|
||||||
|
:lockvar 1 l
|
||||||
|
:try
|
||||||
|
: let l += ['x']
|
||||||
|
: $put ='did :let +='
|
||||||
|
:catch
|
||||||
|
: $put =v:exception[:14]
|
||||||
|
:endtry
|
||||||
|
:$put =string(l)
|
||||||
|
:"
|
||||||
:unlet l
|
:unlet l
|
||||||
:let l = [1, 2, 3, 4]
|
:let l = [1, 2, 3, 4]
|
||||||
:lockvar! l
|
:lockvar! l
|
||||||
|
@ -144,6 +144,9 @@ No extend() of write-protected scope-level variable:
|
|||||||
Vim(put):E742:
|
Vim(put):E742:
|
||||||
No :unlet of variable in locked scope:
|
No :unlet of variable in locked scope:
|
||||||
Vim(unlet):E741:
|
Vim(unlet):E741:
|
||||||
|
No :let += of locked list variable:
|
||||||
|
Vim(let):E741:
|
||||||
|
['a', 'b', 3]
|
||||||
[1, 2, 3, 4]
|
[1, 2, 3, 4]
|
||||||
[1, 2, 3, 4]
|
[1, 2, 3, 4]
|
||||||
[1, 2, 3, 4]
|
[1, 2, 3, 4]
|
||||||
|
@ -571,7 +571,7 @@ static int included_patches[] = {
|
|||||||
// 720 NA
|
// 720 NA
|
||||||
719,
|
719,
|
||||||
718,
|
718,
|
||||||
// 717,
|
717,
|
||||||
716,
|
716,
|
||||||
715,
|
715,
|
||||||
714,
|
714,
|
||||||
|
Loading…
Reference in New Issue
Block a user