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<string> = []
+       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 -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/20220401142758.E2CED1C039E%40moolenaar.net.

Raspunde prin e-mail lui