To: vim_dev@googlegroups.com Subject: Patch 8.2.4662 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.4662 Problem: No error for using out of range list index. Solution: Check list index at script level like in compiled function. (closes #10051) Files: src/vim.h, src/evalvars.c, src/list.c, src/proto/list.pro, src/eval.c, src/vim9execute.c, src/testdir/test_vim9_assign.vim *** ../vim-8.2.4661/src/vim.h 2022-03-30 21:12:16.451923056 +0100 --- src/vim.h 2022-04-01 15:13:38.213866093 +0100 *************** *** 2632,2637 **** --- 2632,2638 ---- #define TFN_NO_DECL 0x20 // only used for GLV_NO_DECL #define TFN_COMPILING 0x40 // only used for GLV_COMPILING #define TFN_NEW_FUNC 0x80 // defining a new function + #define TFN_ASSIGN_WITH_OP 0x100 // only for GLV_ASSIGN_WITH_OP // Values for get_lval() flags argument: #define GLV_QUIET TFN_QUIET // no error messages *************** *** 2639,2644 **** --- 2640,2646 ---- #define GLV_READ_ONLY TFN_READ_ONLY // will not change the var #define GLV_NO_DECL TFN_NO_DECL // assignment without :var or :let #define GLV_COMPILING TFN_COMPILING // variable may be defined later + #define GLV_ASSIGN_WITH_OP TFN_ASSIGN_WITH_OP // assignment with operator #define DO_NOT_FREE_CNT 99999 // refcount for dict or list that should not // be freed. *** ../vim-8.2.4661/src/evalvars.c 2022-03-28 15:22:31.490443719 +0100 --- src/evalvars.c 2022-04-01 15:12:26.618015389 +0100 *************** *** 1647,1659 **** { lval_T lv; char_u *p; // ":let var = expr": Set internal variable. // ":let var: type = expr": Set internal variable with type. // ":let {expr} = expr": Idem, name made with curly braces ! p = get_lval(arg, tv, &lv, FALSE, FALSE, ! (flags & (ASSIGN_NO_DECL | ASSIGN_DECL)) ! ? GLV_NO_DECL : 0, FNE_CHECK_START); if (p != NULL && lv.ll_name != NULL) { if (endchars != NULL && vim_strchr(endchars, --- 1647,1661 ---- { lval_T lv; char_u *p; + int lval_flags = (flags & (ASSIGN_NO_DECL | ASSIGN_DECL)) + ? GLV_NO_DECL : 0; + if (op != NULL && *op != '=') + lval_flags |= GLV_ASSIGN_WITH_OP; // ":let var = expr": Set internal variable. // ":let var: type = expr": Set internal variable with type. // ":let {expr} = expr": Idem, name made with curly braces ! p = get_lval(arg, tv, &lv, FALSE, FALSE, lval_flags, FNE_CHECK_START); if (p != NULL && lv.ll_name != NULL) { if (endchars != NULL && vim_strchr(endchars, *** ../vim-8.2.4661/src/list.c 2022-03-26 16:42:20.095555459 +0000 --- src/list.c 2022-04-01 15:25:19.760694372 +0100 *************** *** 760,777 **** /* * Get the list item in "l" with index "n1". "n1" is adjusted if needed. ! * In Vim9, it is at the end of the list, add an item. * Return NULL if there is no such item. */ listitem_T * ! check_range_index_one(list_T *l, long *n1, int quiet) { ! listitem_T *li = list_find_index(l, n1); if (li == NULL) { // Vim9: Allow for adding an item at the end. ! if (in_vim9script() && *n1 == l->lv_len && l->lv_lock == 0) { list_append_number(l, 0); li = list_find_index(l, n1); --- 760,779 ---- /* * Get the list item in "l" with index "n1". "n1" is adjusted if needed. ! * In Vim9, it is at the end of the list, add an item if "can_append" is TRUE. * Return NULL if there is no such item. */ listitem_T * ! check_range_index_one(list_T *l, long *n1, int can_append, int quiet) { ! long orig_n1 = *n1; ! listitem_T *li = list_find_index(l, n1); if (li == NULL) { // Vim9: Allow for adding an item at the end. ! if (can_append && in_vim9script() ! && *n1 == l->lv_len && l->lv_lock == 0) { list_append_number(l, 0); li = list_find_index(l, n1); *************** *** 779,785 **** if (li == NULL) { if (!quiet) ! semsg(_(e_list_index_out_of_range_nr), *n1); return NULL; } } --- 781,787 ---- if (li == NULL) { if (!quiet) ! semsg(_(e_list_index_out_of_range_nr), orig_n1); return NULL; } } *** ../vim-8.2.4661/src/proto/list.pro 2022-02-02 20:01:21.957210955 +0000 --- src/proto/list.pro 2022-04-01 15:15:20.677665803 +0100 *************** *** 30,36 **** int list_append_number(list_T *l, varnumber_T n); int list_insert_tv(list_T *l, typval_T *tv, listitem_T *item); void list_insert(list_T *l, listitem_T *ni, listitem_T *item); ! listitem_T *check_range_index_one(list_T *l, long *n1, int quiet); int check_range_index_two(list_T *l, long *n1, listitem_T *li1, long *n2, int quiet); int list_assign_range(list_T *dest, list_T *src, long idx1_arg, long idx2, int empty_idx2, char_u *op, char_u *varname); void f_flatten(typval_T *argvars, typval_T *rettv); --- 30,36 ---- int list_append_number(list_T *l, varnumber_T n); int list_insert_tv(list_T *l, typval_T *tv, listitem_T *item); void list_insert(list_T *l, listitem_T *ni, listitem_T *item); ! listitem_T *check_range_index_one(list_T *l, long *n1, int can_append, int quiet); int check_range_index_two(list_T *l, long *n1, listitem_T *li1, long *n2, int quiet); int list_assign_range(list_T *dest, list_T *src, long idx1_arg, long idx2, int empty_idx2, char_u *op, char_u *varname); void f_flatten(typval_T *argvars, typval_T *rettv); *** ../vim-8.2.4661/src/eval.c 2022-03-31 20:02:52.422045605 +0100 --- src/eval.c 2022-04-01 15:15:55.017601744 +0100 *************** *** 1311,1317 **** lp->ll_dict = NULL; lp->ll_list = lp->ll_tv->vval.v_list; ! lp->ll_li = check_range_index_one(lp->ll_list, &lp->ll_n1, quiet); if (lp->ll_li == NULL) { clear_tv(&var2); --- 1311,1318 ---- lp->ll_dict = NULL; lp->ll_list = lp->ll_tv->vval.v_list; ! lp->ll_li = check_range_index_one(lp->ll_list, &lp->ll_n1, ! (flags & GLV_ASSIGN_WITH_OP) == 0, quiet); if (lp->ll_li == NULL) { clear_tv(&var2); *** ../vim-8.2.4661/src/vim9execute.c 2022-03-31 20:02:52.418045613 +0100 --- src/vim9execute.c 2022-04-01 15:17:17.277453841 +0100 *************** *** 1988,1994 **** else n2 = (long)tv_get_number_chk(tv_idx2, NULL); ! li1 = check_range_index_one(tv_dest->vval.v_list, &n1, FALSE); if (li1 == NULL) status = FAIL; else --- 1988,1994 ---- else n2 = (long)tv_get_number_chk(tv_idx2, NULL); ! li1 = check_range_index_one(tv_dest->vval.v_list, &n1, TRUE, FALSE); if (li1 == NULL) status = FAIL; else *** ../vim-8.2.4661/src/testdir/test_vim9_assign.vim 2022-03-20 17:46:01.797053490 +0000 --- src/testdir/test_vim9_assign.vim 2022-04-01 15:01:44.071975955 +0100 *************** *** 288,293 **** --- 288,299 ---- s ..= {a: 2} END v9.CheckDefAndScriptFailure(lines, ['E1105: Cannot convert dict to string', 'E734: Wrong variable type for .='], 2) + + lines =<< trim END + var ls: list = [] + ls[-1] ..= 'foo' + END + v9.CheckDefExecAndScriptFailure(lines, 'E684: list index out of range: -1', 2) enddef def Test_assign_register() *** ../vim-8.2.4661/src/version.c 2022-04-01 13:23:42.960558879 +0100 --- src/version.c 2022-04-01 15:00:22.364358859 +0100 *************** *** 752,753 **** --- 752,755 ---- { /* Add new patch number below this line */ + /**/ + 4662, /**/ -- An indication you must be a manager: You believe you never have any problems in your life, just "issues" and "improvement opportunities". /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///