diff src/list.c @ 23800:57f0e3fd7c05 v8.2.2441

patch 8.2.2441: Vim9: extend() does not give an error for a type mismatch Commit: https://github.com/vim/vim/commit/c03f5c677a1fba99d2379550ccf2391eaa43e2ac Author: Bram Moolenaar <Bram@vim.org> Date: Sun Jan 31 17:48:30 2021 +0100 patch 8.2.2441: Vim9: extend() does not give an error for a type mismatch Problem: Vim9: extend() does not give an error for a type mismatch. Solution: Check the type of the second argument. (closes https://github.com/vim/vim/issues/7760)
author Bram Moolenaar <Bram@vim.org>
date Sun, 31 Jan 2021 18:00:04 +0100
parents 83a69ada0274
children 525c9e218c69
line wrap: on
line diff
--- a/src/list.c
+++ b/src/list.c
@@ -2493,6 +2493,16 @@ f_count(typval_T *argvars, typval_T *ret
     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,7 +2514,7 @@ extend(typval_T *argvars, typval_T *rett
 	if (l1 == NULL)
 	{
 	    emsg(_(e_cannot_extend_null_list));
-	    return;
+	    goto theend;
 	}
 	l2 = argvars[1].vval.v_list;
 	if ((is_new || !value_check_lock(l1->lv_lock, arg_errmsg, TRUE))
@@ -2514,14 +2524,14 @@ extend(typval_T *argvars, typval_T *rett
 	    {
 		l1 = list_copy(l1, FALSE, get_copyID());
 		if (l1 == NULL)
-		    return;
+		    goto theend;
 	    }
 
 	    if (argvars[2].v_type != VAR_UNKNOWN)
 	    {
 		before = (long)tv_get_number_chk(&argvars[2], &error);
 		if (error)
-		    return;		// type error; errmsg already given
+		    goto theend;	// type error; errmsg already given
 
 		if (before == l1->lv_len)
 		    item = NULL;
@@ -2531,12 +2541,14 @@ extend(typval_T *argvars, typval_T *rett
 		    if (item == NULL)
 		    {
 			semsg(_(e_listidx), before);
-			return;
+			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,7 +2571,7 @@ extend(typval_T *argvars, typval_T *rett
 	if (d1 == NULL)
 	{
 	    emsg(_(e_cannot_extend_null_dict));
-	    return;
+	    goto theend;
 	}
 	d2 = argvars[1].vval.v_dict;
 	if ((is_new || !value_check_lock(d1->dv_lock, arg_errmsg, TRUE))
@@ -2569,7 +2581,7 @@ extend(typval_T *argvars, typval_T *rett
 	    {
 		d1 = dict_copy(d1, FALSE, get_copyID());
 		if (d1 == NULL)
-		    return;
+		    goto theend;
 	    }
 
 	    // Check the third argument.
@@ -2579,19 +2591,21 @@ extend(typval_T *argvars, typval_T *rett
 
 		action = tv_get_string_chk(&argvars[2]);
 		if (action == NULL)
-		    return;		// type error; errmsg already given
+		    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);
-		    return;
+		    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,6 +2620,10 @@ extend(typval_T *argvars, typval_T *rett
     }
     else
 	semsg(_(e_listdictarg), is_new ? "extendnew()" : "extend()");
+
+theend:
+    if (type != NULL)
+	clear_type_list(&type_list);
 }
 
 /*