Mercurial > vim
comparison src/eval.c @ 17448:f8cd16838434 v8.1.1722
patch 8.1.1722: error when scriptversion is 2 a making a dictionary access
commit https://github.com/vim/vim/commit/61343f0c44c8e71df04918d033e0a744c0b7f8aa
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Jul 20 21:11:13 2019 +0200
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)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 20 Jul 2019 21:15:04 +0200 |
parents | 40417757dffd |
children | 509542f1fffb |
comparison
equal
deleted
inserted
replaced
17447:c8bdaff91140 | 17448:f8cd16838434 |
---|---|
1484 } | 1484 } |
1485 | 1485 |
1486 /* | 1486 /* |
1487 * Assign the typevalue "tv" to the variable or variables at "arg_start". | 1487 * Assign the typevalue "tv" to the variable or variables at "arg_start". |
1488 * Handles both "var" with any type and "[var, var; var]" with a list type. | 1488 * Handles both "var" with any type and "[var, var; var]" with a list type. |
1489 * When "nextchars" is not NULL it points to a string with characters that | 1489 * When "op" is not NULL it points to a string with characters that |
1490 * must appear after the variable(s). Use "+", "-" or "." for add, subtract | 1490 * must appear after the variable(s). Use "+", "-" or "." for add, subtract |
1491 * or concatenate. | 1491 * or concatenate. |
1492 * Returns OK or FAIL; | 1492 * Returns OK or FAIL; |
1493 */ | 1493 */ |
1494 static int | 1494 static int |
1497 typval_T *tv, | 1497 typval_T *tv, |
1498 int copy, // copy values from "tv", don't move | 1498 int copy, // copy values from "tv", don't move |
1499 int semicolon, // from skip_var_list() | 1499 int semicolon, // from skip_var_list() |
1500 int var_count, // from skip_var_list() | 1500 int var_count, // from skip_var_list() |
1501 int is_const, // lock variables for const | 1501 int is_const, // lock variables for const |
1502 char_u *nextchars) | 1502 char_u *op) |
1503 { | 1503 { |
1504 char_u *arg = arg_start; | 1504 char_u *arg = arg_start; |
1505 list_T *l; | 1505 list_T *l; |
1506 int i; | 1506 int i; |
1507 listitem_T *item; | 1507 listitem_T *item; |
1510 if (*arg != '[') | 1510 if (*arg != '[') |
1511 { | 1511 { |
1512 /* | 1512 /* |
1513 * ":let var = expr" or ":for var in list" | 1513 * ":let var = expr" or ":for var in list" |
1514 */ | 1514 */ |
1515 if (ex_let_one(arg, tv, copy, is_const, nextchars, nextchars) == NULL) | 1515 if (ex_let_one(arg, tv, copy, is_const, op, op) == NULL) |
1516 return FAIL; | 1516 return FAIL; |
1517 return OK; | 1517 return OK; |
1518 } | 1518 } |
1519 | 1519 |
1520 /* | 1520 /* |
1541 item = l->lv_first; | 1541 item = l->lv_first; |
1542 while (*arg != ']') | 1542 while (*arg != ']') |
1543 { | 1543 { |
1544 arg = skipwhite(arg + 1); | 1544 arg = skipwhite(arg + 1); |
1545 arg = ex_let_one(arg, &item->li_tv, TRUE, is_const, | 1545 arg = ex_let_one(arg, &item->li_tv, TRUE, is_const, |
1546 (char_u *)",;]", nextchars); | 1546 (char_u *)",;]", op); |
1547 item = item->li_next; | 1547 item = item->li_next; |
1548 if (arg == NULL) | 1548 if (arg == NULL) |
1549 return FAIL; | 1549 return FAIL; |
1550 | 1550 |
1551 arg = skipwhite(arg); | 1551 arg = skipwhite(arg); |
1566 ltv.v_lock = 0; | 1566 ltv.v_lock = 0; |
1567 ltv.vval.v_list = l; | 1567 ltv.vval.v_list = l; |
1568 l->lv_refcount = 1; | 1568 l->lv_refcount = 1; |
1569 | 1569 |
1570 arg = ex_let_one(skipwhite(arg + 1), <v, FALSE, is_const, | 1570 arg = ex_let_one(skipwhite(arg + 1), <v, FALSE, is_const, |
1571 (char_u *)"]", nextchars); | 1571 (char_u *)"]", op); |
1572 clear_tv(<v); | 1572 clear_tv(<v); |
1573 if (arg == NULL) | 1573 if (arg == NULL) |
1574 return FAIL; | 1574 return FAIL; |
1575 break; | 1575 break; |
1576 } | 1576 } |
7353 dict_T *selfdict = NULL; | 7353 dict_T *selfdict = NULL; |
7354 char_u *s; | 7354 char_u *s; |
7355 int len; | 7355 int len; |
7356 typval_T functv; | 7356 typval_T functv; |
7357 | 7357 |
7358 // "." is ".name" lookup when we found a dict or when evaluating and | |
7359 // scriptversion is at least 2, where string concatenation is "..". | |
7358 while (ret == OK | 7360 while (ret == OK |
7359 && (**arg == '[' | 7361 && (**arg == '[' |
7360 || (**arg == '.' && rettv->v_type == VAR_DICT) | 7362 || (**arg == '.' && (rettv->v_type == VAR_DICT |
7363 || (!evaluate | |
7364 && (*arg)[1] != '.' | |
7365 && current_sctx.sc_version >= 2))) | |
7361 || (**arg == '(' && (!evaluate || rettv->v_type == VAR_FUNC | 7366 || (**arg == '(' && (!evaluate || rettv->v_type == VAR_FUNC |
7362 || rettv->v_type == VAR_PARTIAL))) | 7367 || rettv->v_type == VAR_PARTIAL))) |
7363 && !VIM_ISWHITE(*(*arg - 1))) | 7368 && !VIM_ISWHITE(*(*arg - 1))) |
7364 { | 7369 { |
7365 if (**arg == '(') | 7370 if (**arg == '(') |