changeset 21481:279b3415947f v8.2.1291

patch 8.2.1291: Vim9: type of varargs items is not checked Commit: https://github.com/vim/vim/commit/24aa48b7a265c24e18f0f978dfe0255e138e2b90 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Jul 25 16:33:02 2020 +0200 patch 8.2.1291: Vim9: type of varargs items is not checked Problem: Vim9: type of varargs items is not checked. Solution: Check the list item types. (closes https://github.com/vim/vim/issues/6523)
author Bram Moolenaar <Bram@vim.org>
date Sat, 25 Jul 2020 16:45:04 +0200
parents 440d226ff54a
children f15b6aaa0011
files src/testdir/test_vim9_func.vim src/version.c src/vim9execute.c
diffstat 3 files changed, 70 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/testdir/test_vim9_func.vim
+++ b/src/testdir/test_vim9_func.vim
@@ -164,7 +164,55 @@ def Test_call_def_varargs()
   assert_equal('one,foo', MyDefVarargs('one'))
   assert_equal('one,two', MyDefVarargs('one', 'two'))
   assert_equal('one,two,three', MyDefVarargs('one', 'two', 'three'))
-  call CheckDefFailure(['MyDefVarargs("one", 22)'], 'E1013: argument 2: type mismatch, expected string but got number')
+  CheckDefFailure(['MyDefVarargs("one", 22)'],
+      'E1013: argument 2: type mismatch, expected string but got number')
+  CheckDefFailure(['MyDefVarargs("one", "two", 123)'],
+      'E1013: argument 3: type mismatch, expected string but got number')
+
+  let lines =<< trim END
+      vim9script
+      def Func(...l: list<string>)
+        echo l
+      enddef
+      Func('a', 'b', 'c')
+  END
+  CheckScriptSuccess(lines)
+
+  lines =<< trim END
+      vim9script
+      def Func(...l: list<string>)
+        echo l
+      enddef
+      Func()
+  END
+  CheckScriptSuccess(lines)
+
+  lines =<< trim END
+      vim9script
+      def Func(...l: list<string>)
+        echo l
+      enddef
+      Func(1, 2, 3)
+  END
+  CheckScriptFailure(lines, 'E1013:')
+
+  lines =<< trim END
+      vim9script
+      def Func(...l: list<string>)
+        echo l
+      enddef
+      Func('a', 9)
+  END
+  CheckScriptFailure(lines, 'E1013:')
+
+  lines =<< trim END
+      vim9script
+      def Func(...l: list<string>)
+        echo l
+      enddef
+      Func(1, 'a')
+  END
+  CheckScriptFailure(lines, 'E1013:')
 enddef
 
 let s:value = ''
--- a/src/version.c
+++ b/src/version.c
@@ -755,6 +755,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1291,
+/**/
     1290,
 /**/
     1289,
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -755,9 +755,27 @@ call_def_function(
 	    argc -= vararg_count;
 	if (exe_newlist(vararg_count, &ectx) == FAIL)
 	    goto failed_early;
+
+	// Check the type of the list items.
+	tv = STACK_TV_BOT(-1);
+	if (ufunc->uf_va_type != NULL
+		&& ufunc->uf_va_type->tt_member != &t_any
+		&& tv->vval.v_list != NULL)
+	{
+	    type_T	*expected = ufunc->uf_va_type->tt_member;
+	    listitem_T	*li = tv->vval.v_list->lv_first;
+
+	    for (idx = 0; idx < vararg_count; ++idx)
+	    {
+		if (check_typval_type(expected, &li->li_tv) == FAIL)
+		    goto failed_early;
+		li = li->li_next;
+	    }
+	}
+
 	if (defcount > 0)
 	    // Move varargs list to below missing default arguments.
-	    *STACK_TV_BOT(defcount- 1) = *STACK_TV_BOT(-1);
+	    *STACK_TV_BOT(defcount - 1) = *STACK_TV_BOT(-1);
 	--ectx.ec_stack.ga_len;
     }