diff src/vim9compile.c @ 23266:00f7cd9b6033 v8.2.2179

patch 8.2.2179: Vim9: crash when indexing a dict with a number Commit: https://github.com/vim/vim/commit/4f5e39775616795ac7d1c01bf15a1bd316feb387 Author: Bram Moolenaar <Bram@vim.org> Date: Mon Dec 21 17:30:50 2020 +0100 patch 8.2.2179: Vim9: crash when indexing a dict with a number Problem: Vim9: crash when indexing a dict with a number. Solution: Add ISN_STOREINDEX. (closes https://github.com/vim/vim/issues/7513)
author Bram Moolenaar <Bram@vim.org>
date Mon, 21 Dec 2020 17:45:04 +0100
parents 4b7e996354e0
children 112fa621b127
line wrap: on
line diff
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -5904,26 +5904,22 @@ compile_assignment(char_u *arg, exarg_T 
 
 	    if (type == &t_any)
 	    {
-		type_T	    *idx_type = ((type_T **)stack->ga_data)[
-							    stack->ga_len - 1];
-		// Index on variable of unknown type: guess the type from the
-		// index type: number is dict, otherwise dict.
-		// TODO: should do the assignment at runtime
-		if (idx_type->tt_type == VAR_NUMBER)
-		    type = &t_list_any;
-		else
-		    type = &t_dict_any;
+		// Index on variable of unknown type: check at runtime.
+		dest_type = VAR_ANY;
 	    }
-	    dest_type = type->tt_type;
-	    if (dest_type == VAR_DICT
-		    && may_generate_2STRING(-1, cctx) == FAIL)
-		goto theend;
-	    if (dest_type == VAR_LIST
-		    && ((type_T **)stack->ga_data)[stack->ga_len - 1]->tt_type
+	    else
+	    {
+		dest_type = type->tt_type;
+		if (dest_type == VAR_DICT
+			&& may_generate_2STRING(-1, cctx) == FAIL)
+		    goto theend;
+		if (dest_type == VAR_LIST
+		     && ((type_T **)stack->ga_data)[stack->ga_len - 1]->tt_type
 								 != VAR_NUMBER)
-	    {
-		emsg(_(e_number_exp));
-		goto theend;
+		{
+		    emsg(_(e_number_exp));
+		    goto theend;
+		}
 	    }
 
 	    // Load the dict or list.  On the stack we then have:
@@ -5956,15 +5952,14 @@ compile_assignment(char_u *arg, exarg_T 
 	    else
 		generate_loadvar(cctx, dest, name, lvar, type);
 
-	    if (dest_type == VAR_LIST)
+	    if (dest_type == VAR_LIST || dest_type == VAR_DICT
+						       || dest_type == VAR_ANY)
 	    {
-		if (generate_instr_drop(cctx, ISN_STORELIST, 3) == FAIL)
+		isn_T	*isn = generate_instr_drop(cctx, ISN_STOREINDEX, 3);
+
+		if (isn == NULL)
 		    goto theend;
-	    }
-	    else if (dest_type == VAR_DICT)
-	    {
-		if (generate_instr_drop(cctx, ISN_STOREDICT, 3) == FAIL)
-		    goto theend;
+		isn->isn_arg.vartype = dest_type;
 	    }
 	    else
 	    {
@@ -8194,8 +8189,7 @@ delete_instr(isn_T *isn)
 	case ISN_SHUFFLE:
 	case ISN_SLICE:
 	case ISN_STORE:
-	case ISN_STOREDICT:
-	case ISN_STORELIST:
+	case ISN_STOREINDEX:
 	case ISN_STORENR:
 	case ISN_STOREOUTER:
 	case ISN_STOREREG: