Mercurial > vim
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; } /*