diff src/vim9script.c @ 23362:f181fe2150ab v8.2.2224

patch 8.2.2224: Vim9: crash if script reloaded with different variable type Commit: https://github.com/vim/vim/commit/07a65d26e7d76ad22d6ef23b50c0faa25e435e02 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Dec 26 20:09:15 2020 +0100 patch 8.2.2224: Vim9: crash if script reloaded with different variable type Problem: Vim9: crash if script reloaded with different variable type. Solution: Check the type when accessing the variable.
author Bram Moolenaar <Bram@vim.org>
date Sat, 26 Dec 2020 20:15:04 +0100
parents b3142fc0a414
children 17a0e32eefd4
line wrap: on
line diff
--- a/src/vim9script.c
+++ b/src/vim9script.c
@@ -591,36 +591,37 @@ vim9_declare_scriptvar(exarg_T *eap, cha
 /*
  * Vim9 part of adding a script variable: add it to sn_all_vars (lookup by name
  * with a hashtable) and sn_var_vals (lookup by index).
+ * When "create" is TRUE this is a new variable, otherwise find and update an
+ * existing variable.
  * When "type" is NULL use "tv" for the type.
  */
     void
-add_vim9_script_var(dictitem_T *di, typval_T *tv, type_T *type)
+update_vim9_script_var(int create, dictitem_T *di, typval_T *tv, type_T *type)
 {
-    scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
+    scriptitem_T    *si = SCRIPT_ITEM(current_sctx.sc_sid);
+    hashitem_T	    *hi;
+    svar_T	    *sv;
 
-    // Store a pointer to the typval_T, so that it can be found by
-    // index instead of using a hastab lookup.
-    if (ga_grow(&si->sn_var_vals, 1) == OK)
+    if (create)
     {
-	svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data)
-						      + si->sn_var_vals.ga_len;
-	hashitem_T *hi;
-	sallvar_T *newsav = (sallvar_T *)alloc_clear(
+	sallvar_T	    *newsav;
+
+	// Store a pointer to the typval_T, so that it can be found by index
+	// instead of using a hastab lookup.
+	if (ga_grow(&si->sn_var_vals, 1) == FAIL)
+	    return;
+
+	sv = ((svar_T *)si->sn_var_vals.ga_data) + si->sn_var_vals.ga_len;
+	newsav = (sallvar_T *)alloc_clear(
 				       sizeof(sallvar_T) + STRLEN(di->di_key));
-
 	if (newsav == NULL)
 	    return;
 
 	sv->sv_tv = &di->di_tv;
-	if (type == NULL)
-	    sv->sv_type = typval2type(tv, &si->sn_type_list);
-	else
-	    sv->sv_type = type;
 	sv->sv_const = (di->di_flags & DI_FLAGS_LOCK) ? ASSIGN_CONST : 0;
 	sv->sv_export = is_export;
 	newsav->sav_var_vals_idx = si->sn_var_vals.ga_len;
 	++si->sn_var_vals.ga_len;
-
 	STRCPY(&newsav->sav_key, di->di_key);
 	sv->sv_name = newsav->sav_key;
 	newsav->sav_di = di;
@@ -639,10 +640,21 @@ add_vim9_script_var(dictitem_T *di, typv
 	else
 	    // new variable name
 	    hash_add(&si->sn_all_vars.dv_hashtab, newsav->sav_key);
+    }
+    else
+    {
+	sv = find_typval_in_script(&di->di_tv);
+    }
+    if (sv != NULL)
+    {
+	if (type == NULL)
+	    sv->sv_type = typval2type(tv, &si->sn_type_list);
+	else
+	    sv->sv_type = type;
+    }
 
-	// let ex_export() know the export worked.
-	is_export = FALSE;
-    }
+    // let ex_export() know the export worked.
+    is_export = FALSE;
 }
 
 /*