Patch 8.2.2441
Problem:    Vim9: extend() does not give an error for a type mismatch.
Solution:   Check the type of the second argument. (closes #7760)
Files:      src/list.c, src/testdir/test_vim9_builtin.vim


*** ../vim-8.2.2440/src/list.c  2021-01-17 13:21:14.962687183 +0100
--- src/list.c  2021-01-31 17:38:24.067976404 +0100
***************
*** 2493,2498 ****
--- 2493,2508 ----
      static void
  extend(typval_T *argvars, typval_T *rettv, char_u *arg_errmsg, int is_new)
  {
+     type_T    *type = NULL;
+     garray_T  type_list;
+ 
+     if (!is_new && in_vim9script())
+     {
+       // Check that map() does not change the type of the dict.
+       ga_init2(&type_list, sizeof(type_T *), 10);
+       type = typval2type(argvars, &type_list);
+     }
+ 
      if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST)
      {
        list_T          *l1, *l2;
***************
*** 2504,2510 ****
        if (l1 == NULL)
        {
            emsg(_(e_cannot_extend_null_list));
!           return;
        }
        l2 = argvars[1].vval.v_list;
        if ((is_new || !value_check_lock(l1->lv_lock, arg_errmsg, TRUE))
--- 2514,2520 ----
        if (l1 == NULL)
        {
            emsg(_(e_cannot_extend_null_list));
!           goto theend;
        }
        l2 = argvars[1].vval.v_list;
        if ((is_new || !value_check_lock(l1->lv_lock, arg_errmsg, TRUE))
***************
*** 2514,2527 ****
            {
                l1 = list_copy(l1, FALSE, get_copyID());
                if (l1 == NULL)
!                   return;
            }
  
            if (argvars[2].v_type != VAR_UNKNOWN)
            {
                before = (long)tv_get_number_chk(&argvars[2], &error);
                if (error)
!                   return;             // type error; errmsg already given
  
                if (before == l1->lv_len)
                    item = NULL;
--- 2524,2537 ----
            {
                l1 = list_copy(l1, FALSE, get_copyID());
                if (l1 == NULL)
!                   goto theend;
            }
  
            if (argvars[2].v_type != VAR_UNKNOWN)
            {
                before = (long)tv_get_number_chk(&argvars[2], &error);
                if (error)
!                   goto theend;        // type error; errmsg already given
  
                if (before == l1->lv_len)
                    item = NULL;
***************
*** 2531,2542 ****
                    if (item == NULL)
                    {
                        semsg(_(e_listidx), before);
!                       return;
                    }
                }
            }
            else
                item = NULL;
            list_extend(l1, l2, item);
  
            if (is_new)
--- 2541,2554 ----
                    if (item == NULL)
                    {
                        semsg(_(e_listidx), before);
!                       goto theend;
                    }
                }
            }
            else
                item = NULL;
+           if (type != NULL && check_typval_type(type, &argvars[1], 2) == FAIL)
+               goto theend;
            list_extend(l1, l2, item);
  
            if (is_new)
***************
*** 2559,2565 ****
        if (d1 == NULL)
        {
            emsg(_(e_cannot_extend_null_dict));
!           return;
        }
        d2 = argvars[1].vval.v_dict;
        if ((is_new || !value_check_lock(d1->dv_lock, arg_errmsg, TRUE))
--- 2571,2577 ----
        if (d1 == NULL)
        {
            emsg(_(e_cannot_extend_null_dict));
!           goto theend;
        }
        d2 = argvars[1].vval.v_dict;
        if ((is_new || !value_check_lock(d1->dv_lock, arg_errmsg, TRUE))
***************
*** 2569,2575 ****
            {
                d1 = dict_copy(d1, FALSE, get_copyID());
                if (d1 == NULL)
!                   return;
            }
  
            // Check the third argument.
--- 2581,2587 ----
            {
                d1 = dict_copy(d1, FALSE, get_copyID());
                if (d1 == NULL)
!                   goto theend;
            }
  
            // Check the third argument.
***************
*** 2579,2597 ****
  
                action = tv_get_string_chk(&argvars[2]);
                if (action == NULL)
!                   return;             // type error; errmsg already given
                for (i = 0; i < 3; ++i)
                    if (STRCMP(action, av[i]) == 0)
                        break;
                if (i == 3)
                {
                    semsg(_(e_invarg2), action);
!                   return;
                }
            }
            else
                action = (char_u *)"force";
  
            dict_extend(d1, d2, action);
  
            if (is_new)
--- 2591,2611 ----
  
                action = tv_get_string_chk(&argvars[2]);
                if (action == NULL)
!                   goto theend;        // type error; errmsg already given
                for (i = 0; i < 3; ++i)
                    if (STRCMP(action, av[i]) == 0)
                        break;
                if (i == 3)
                {
                    semsg(_(e_invarg2), action);
!                   goto theend;
                }
            }
            else
                action = (char_u *)"force";
  
+           if (type != NULL && check_typval_type(type, &argvars[1], 2) == FAIL)
+               goto theend;
            dict_extend(d1, d2, action);
  
            if (is_new)
***************
*** 2606,2611 ****
--- 2620,2629 ----
      }
      else
        semsg(_(e_listdictarg), is_new ? "extendnew()" : "extend()");
+ 
+ theend:
+     if (type != NULL)
+       clear_type_list(&type_list);
  }
  
  /*
*** ../vim-8.2.2440/src/testdir/test_vim9_builtin.vim   2021-01-31 
13:08:16.164367438 +0100
--- src/testdir/test_vim9_builtin.vim   2021-01-31 17:47:07.650564561 +0100
***************
*** 240,258 ****
  enddef
  
  def Test_extend_arg_types()
!   assert_equal([1, 2, 3], extend([1, 2], [3]))
!   assert_equal([3, 1, 2], extend([1, 2], [3], 0))
!   assert_equal([1, 3, 2], extend([1, 2], [3], 1))
!   assert_equal([1, 3, 2], extend([1, 2], [3], s:number_one))
! 
!   assert_equal({a: 1, b: 2, c: 3}, extend({a: 1, b: 2}, {c: 3}))
!   assert_equal({a: 1, b: 4}, extend({a: 1, b: 2}, {b: 4}))
!   assert_equal({a: 1, b: 2}, extend({a: 1, b: 2}, {b: 4}, 'keep'))
!   assert_equal({a: 1, b: 2}, extend({a: 1, b: 2}, {b: 4}, s:string_keep))
! 
!   var res: list<dict<any>>
!   extend(res, mapnew([1, 2], (_, v) => ({})))
!   assert_equal([{}, {}], res)
  
    CheckDefFailure(['extend([1, 2], 3)'], 'E1013: Argument 2: type mismatch, 
expected list<number> but got number')
    CheckDefFailure(['extend([1, 2], ["x"])'], 'E1013: Argument 2: type 
mismatch, expected list<number> but got list<string>')
--- 240,263 ----
  enddef
  
  def Test_extend_arg_types()
!   g:number_one = 1
!   g:string_keep = 'keep'
!   var lines =<< trim END
!       assert_equal([1, 2, 3], extend([1, 2], [3]))
!       assert_equal([3, 1, 2], extend([1, 2], [3], 0))
!       assert_equal([1, 3, 2], extend([1, 2], [3], 1))
!       assert_equal([1, 3, 2], extend([1, 2], [3], g:number_one))
! 
!       assert_equal({a: 1, b: 2, c: 3}, extend({a: 1, b: 2}, {c: 3}))
!       assert_equal({a: 1, b: 4}, extend({a: 1, b: 2}, {b: 4}))
!       assert_equal({a: 1, b: 2}, extend({a: 1, b: 2}, {b: 4}, 'keep'))
!       assert_equal({a: 1, b: 2}, extend({a: 1, b: 2}, {b: 4}, g:string_keep))
! 
!       var res: list<dict<any>>
!       extend(res, mapnew([1, 2], (_, v) => ({})))
!       assert_equal([{}, {}], res)
!   END
!   CheckDefAndScriptSuccess(lines)
  
    CheckDefFailure(['extend([1, 2], 3)'], 'E1013: Argument 2: type mismatch, 
expected list<number> but got number')
    CheckDefFailure(['extend([1, 2], ["x"])'], 'E1013: Argument 2: type 
mismatch, expected list<number> but got list<string>')
***************
*** 300,307 ****
         var d: dict<number> = {a: 1}
         extend(d, {b: 'x'})
    END
!   CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected 
dict<number> but got dict<string>', 2)
!   CheckScriptFailure(['vim9script'] + lines, 'E1012:', 3)
  
    lines =<< trim END
         var d: dict<number> = {a: 1}
--- 305,311 ----
         var d: dict<number> = {a: 1}
         extend(d, {b: 'x'})
    END
!   CheckDefAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected 
dict<number> but got dict<string>', 2)
  
    lines =<< trim END
         var d: dict<number> = {a: 1}
***************
*** 326,333 ****
         var l: list<number> = [1]
         extend(l, ['x'])
    END
!   CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected 
list<number> but got list<string>', 2)
!   CheckScriptFailure(['vim9script'] + lines, 'E1012:', 3)
  
    lines =<< trim END
         var l: list<number> = [1]
--- 330,336 ----
         var l: list<number> = [1]
         extend(l, ['x'])
    END
!   CheckDefAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected 
list<number> but got list<string>', 2)
  
    lines =<< trim END
         var l: list<number> = [1]
*** ../vim-8.2.2440/src/version.c       2021-01-31 17:02:06.282490066 +0100
--- src/version.c       2021-01-31 17:47:47.474446441 +0100
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     2441,
  /**/

-- 
In his lifetime van Gogh painted 486 oil paintings. Oddly enough, 8975
of them are to be found in the United States.

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            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/202101311649.10VGn0mI1002395%40masaka.moolenaar.net.

Raspunde prin e-mail lui