Patch 8.2.2441

4 views
Skip to first unread message

Bram Moolenaar

unread,
Jan 31, 2021, 11:49:07 AM1/31/21
to vim...@googlegroups.com

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 -- Br...@Moolenaar.net -- 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 ///
Reply all
Reply to author
Forward
0 new messages