To: vim_dev@googlegroups.com Subject: Patch 8.2.2441 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ 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> ! extend(res, mapnew([1, 2], (_, v) => ({}))) ! assert_equal([{}, {}], res) CheckDefFailure(['extend([1, 2], 3)'], 'E1013: Argument 2: type mismatch, expected list but got number') CheckDefFailure(['extend([1, 2], ["x"])'], 'E1013: Argument 2: type mismatch, expected list but got list') --- 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> ! extend(res, mapnew([1, 2], (_, v) => ({}))) ! assert_equal([{}, {}], res) ! END ! CheckDefAndScriptSuccess(lines) CheckDefFailure(['extend([1, 2], 3)'], 'E1013: Argument 2: type mismatch, expected list but got number') CheckDefFailure(['extend([1, 2], ["x"])'], 'E1013: Argument 2: type mismatch, expected list but got list') *************** *** 300,307 **** var d: dict = {a: 1} extend(d, {b: 'x'}) END ! CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected dict but got dict', 2) ! CheckScriptFailure(['vim9script'] + lines, 'E1012:', 3) lines =<< trim END var d: dict = {a: 1} --- 305,311 ---- var d: dict = {a: 1} extend(d, {b: 'x'}) END ! CheckDefAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected dict but got dict', 2) lines =<< trim END var d: dict = {a: 1} *************** *** 326,333 **** var l: list = [1] extend(l, ['x']) END ! CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected list but got list', 2) ! CheckScriptFailure(['vim9script'] + lines, 'E1012:', 3) lines =<< trim END var l: list = [1] --- 330,336 ---- var l: list = [1] extend(l, ['x']) END ! CheckDefAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected list but got list', 2) lines =<< trim END var l: list = [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 -- Bram@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 ///