0
0
mirror of https://github.com/vim/vim.git synced 2025-09-24 03:44:06 -04:00

patch 8.1.1722: error when scriptversion is 2 a making a dictionary access

Problem:    Error when scriptversion is 2 a making a dictionary access.
Solution:   Parse the subscript even when not evaluating the sub-expression.
            (closes #4704)
This commit is contained in:
Bram Moolenaar
2019-07-20 21:11:13 +02:00
parent 63187f7932
commit 61343f0c44
3 changed files with 20 additions and 6 deletions

View File

@@ -1486,7 +1486,7 @@ ex_let_const(exarg_T *eap, int is_const)
/* /*
* Assign the typevalue "tv" to the variable or variables at "arg_start". * Assign the typevalue "tv" to the variable or variables at "arg_start".
* Handles both "var" with any type and "[var, var; var]" with a list type. * Handles both "var" with any type and "[var, var; var]" with a list type.
* When "nextchars" is not NULL it points to a string with characters that * When "op" is not NULL it points to a string with characters that
* must appear after the variable(s). Use "+", "-" or "." for add, subtract * must appear after the variable(s). Use "+", "-" or "." for add, subtract
* or concatenate. * or concatenate.
* Returns OK or FAIL; * Returns OK or FAIL;
@@ -1499,7 +1499,7 @@ ex_let_vars(
int semicolon, // from skip_var_list() int semicolon, // from skip_var_list()
int var_count, // from skip_var_list() int var_count, // from skip_var_list()
int is_const, // lock variables for const int is_const, // lock variables for const
char_u *nextchars) char_u *op)
{ {
char_u *arg = arg_start; char_u *arg = arg_start;
list_T *l; list_T *l;
@@ -1512,7 +1512,7 @@ ex_let_vars(
/* /*
* ":let var = expr" or ":for var in list" * ":let var = expr" or ":for var in list"
*/ */
if (ex_let_one(arg, tv, copy, is_const, nextchars, nextchars) == NULL) if (ex_let_one(arg, tv, copy, is_const, op, op) == NULL)
return FAIL; return FAIL;
return OK; return OK;
} }
@@ -1543,7 +1543,7 @@ ex_let_vars(
{ {
arg = skipwhite(arg + 1); arg = skipwhite(arg + 1);
arg = ex_let_one(arg, &item->li_tv, TRUE, is_const, arg = ex_let_one(arg, &item->li_tv, TRUE, is_const,
(char_u *)",;]", nextchars); (char_u *)",;]", op);
item = item->li_next; item = item->li_next;
if (arg == NULL) if (arg == NULL)
return FAIL; return FAIL;
@@ -1568,7 +1568,7 @@ ex_let_vars(
l->lv_refcount = 1; l->lv_refcount = 1;
arg = ex_let_one(skipwhite(arg + 1), &ltv, FALSE, is_const, arg = ex_let_one(skipwhite(arg + 1), &ltv, FALSE, is_const,
(char_u *)"]", nextchars); (char_u *)"]", op);
clear_tv(&ltv); clear_tv(&ltv);
if (arg == NULL) if (arg == NULL)
return FAIL; return FAIL;
@@ -7355,9 +7355,14 @@ handle_subscript(
int len; int len;
typval_T functv; typval_T functv;
// "." is ".name" lookup when we found a dict or when evaluating and
// scriptversion is at least 2, where string concatenation is "..".
while (ret == OK while (ret == OK
&& (**arg == '[' && (**arg == '['
|| (**arg == '.' && rettv->v_type == VAR_DICT) || (**arg == '.' && (rettv->v_type == VAR_DICT
|| (!evaluate
&& (*arg)[1] != '.'
&& current_sctx.sc_version >= 2)))
|| (**arg == '(' && (!evaluate || rettv->v_type == VAR_FUNC || (**arg == '(' && (!evaluate || rettv->v_type == VAR_FUNC
|| rettv->v_type == VAR_PARTIAL))) || rettv->v_type == VAR_PARTIAL)))
&& !VIM_ISWHITE(*(*arg - 1))) && !VIM_ISWHITE(*(*arg - 1)))

View File

@@ -176,6 +176,13 @@ func Test_vvar_scriptversion2()
call assert_true(v:versionlong > 8011525) call assert_true(v:versionlong > 8011525)
endfunc endfunc
func Test_dict_access_scriptversion2()
let l:x = {'foo': 1}
call assert_false(0 && l:x.foo)
call assert_true(1 && l:x.foo)
endfunc
func Test_scriptversion() func Test_scriptversion()
call writefile(['scriptversion 9'], 'Xversionscript') call writefile(['scriptversion 9'], 'Xversionscript')
call assert_fails('source Xversionscript', 'E999:') call assert_fails('source Xversionscript', 'E999:')

View File

@@ -777,6 +777,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
1722,
/**/ /**/
1721, 1721,
/**/ /**/