comparison src/vim9execute.c @ 25461:891d08245543 v8.2.3267

patch 8.2.3267: Vim9: crash when disassembling using deleted script variable Commit: https://github.com/vim/vim/commit/6db660bed9ed5063f8c6e0fadeef32d44bbd017d Author: Bram Moolenaar <Bram@vim.org> Date: Sun Aug 1 14:08:54 2021 +0200 patch 8.2.3267: Vim9: crash when disassembling using deleted script variable Problem: Vim9: crash when disassembling a function that uses a deleted script variable. Solution: Check the variable still exists. (closes #8683)
author Bram Moolenaar <Bram@vim.org>
date Sun, 01 Aug 2021 14:15:04 +0200
parents effe5f2b4d01
children 038eb6d9003a
comparison
equal deleted inserted replaced
25460:2e4c691247c1 25461:891d08245543
1252 if (start_byte >= (long)slen || end_byte <= start_byte) 1252 if (start_byte >= (long)slen || end_byte <= start_byte)
1253 return NULL; 1253 return NULL;
1254 return vim_strnsave(str + start_byte, end_byte - start_byte); 1254 return vim_strnsave(str + start_byte, end_byte - start_byte);
1255 } 1255 }
1256 1256
1257 /*
1258 * Get a script variable for ISN_STORESCRIPT and ISN_LOADSCRIPT.
1259 * When "dfunc_idx" is negative don't give an error.
1260 * Returns NULL for an error.
1261 */
1257 static svar_T * 1262 static svar_T *
1258 get_script_svar(scriptref_T *sref, ectx_T *ectx) 1263 get_script_svar(scriptref_T *sref, int dfunc_idx)
1259 { 1264 {
1260 scriptitem_T *si = SCRIPT_ITEM(sref->sref_sid); 1265 scriptitem_T *si = SCRIPT_ITEM(sref->sref_sid);
1261 dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data) 1266 dfunc_T *dfunc = dfunc_idx < 0 ? NULL
1262 + ectx->ec_dfunc_idx; 1267 : ((dfunc_T *)def_functions.ga_data) + dfunc_idx;
1263 svar_T *sv; 1268 svar_T *sv;
1264 1269
1265 if (sref->sref_seq != si->sn_script_seq) 1270 if (sref->sref_seq != si->sn_script_seq)
1266 { 1271 {
1267 // The script was reloaded after the function was 1272 // The script was reloaded after the function was compiled, the
1268 // compiled, the script_idx may not be valid. 1273 // script_idx may not be valid.
1269 semsg(_(e_script_variable_invalid_after_reload_in_function_str), 1274 if (dfunc != NULL)
1270 dfunc->df_ufunc->uf_name_exp); 1275 semsg(_(e_script_variable_invalid_after_reload_in_function_str),
1276 printable_func_name(dfunc->df_ufunc));
1271 return NULL; 1277 return NULL;
1272 } 1278 }
1273 sv = ((svar_T *)si->sn_var_vals.ga_data) + sref->sref_idx; 1279 sv = ((svar_T *)si->sn_var_vals.ga_data) + sref->sref_idx;
1274 if (!equal_type(sv->sv_type, sref->sref_type, 0)) 1280 if (!equal_type(sv->sv_type, sref->sref_type, 0))
1275 { 1281 {
1276 emsg(_(e_script_variable_type_changed)); 1282 if (dfunc != NULL)
1283 emsg(_(e_script_variable_type_changed));
1277 return NULL; 1284 return NULL;
1278 } 1285 }
1279 return sv; 1286 return sv;
1280 } 1287 }
1281 1288
1974 case ISN_LOADSCRIPT: 1981 case ISN_LOADSCRIPT:
1975 { 1982 {
1976 scriptref_T *sref = iptr->isn_arg.script.scriptref; 1983 scriptref_T *sref = iptr->isn_arg.script.scriptref;
1977 svar_T *sv; 1984 svar_T *sv;
1978 1985
1979 sv = get_script_svar(sref, ectx); 1986 sv = get_script_svar(sref, ectx->ec_dfunc_idx);
1980 if (sv == NULL) 1987 if (sv == NULL)
1981 goto theend; 1988 goto theend;
1982 allocate_if_null(sv->sv_tv); 1989 allocate_if_null(sv->sv_tv);
1983 if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL)) 1990 if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
1984 goto theend; 1991 goto theend;
2187 case ISN_STORESCRIPT: 2194 case ISN_STORESCRIPT:
2188 { 2195 {
2189 scriptref_T *sref = iptr->isn_arg.script.scriptref; 2196 scriptref_T *sref = iptr->isn_arg.script.scriptref;
2190 svar_T *sv; 2197 svar_T *sv;
2191 2198
2192 sv = get_script_svar(sref, ectx); 2199 sv = get_script_svar(sref, ectx->ec_dfunc_idx);
2193 if (sv == NULL) 2200 if (sv == NULL)
2194 goto theend; 2201 goto theend;
2195 --ectx->ec_stack.ga_len; 2202 --ectx->ec_stack.ga_len;
2196 2203
2197 // "const" and "final" are checked at compile time, locking 2204 // "const" and "final" are checked at compile time, locking
4940 smsg("%s%4d LOADV v:%s", pfx, current, 4947 smsg("%s%4d LOADV v:%s", pfx, current,
4941 get_vim_var_name(iptr->isn_arg.number)); 4948 get_vim_var_name(iptr->isn_arg.number));
4942 break; 4949 break;
4943 case ISN_LOADSCRIPT: 4950 case ISN_LOADSCRIPT:
4944 { 4951 {
4945 scriptref_T *sref = iptr->isn_arg.script.scriptref; 4952 scriptref_T *sref = iptr->isn_arg.script.scriptref;
4946 scriptitem_T *si = SCRIPT_ITEM(sref->sref_sid); 4953 scriptitem_T *si = SCRIPT_ITEM(sref->sref_sid);
4947 svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data) 4954 svar_T *sv;
4948 + sref->sref_idx; 4955
4949 4956 sv = get_script_svar(sref, -1);
4950 smsg("%s%4d LOADSCRIPT %s-%d from %s", pfx, current, 4957 if (sv == NULL)
4958 smsg("%s%4d LOADSCRIPT [deleted] from %s",
4959 pfx, current, si->sn_name);
4960 else
4961 smsg("%s%4d LOADSCRIPT %s-%d from %s", pfx, current,
4951 sv->sv_name, 4962 sv->sv_name,
4952 sref->sref_idx, 4963 sref->sref_idx,
4953 si->sn_name); 4964 si->sn_name);
4954 } 4965 }
4955 break; 4966 break;
4994 break; 5005 break;
4995 case ISN_LOADENV: 5006 case ISN_LOADENV:
4996 smsg("%s%4d LOADENV %s", pfx, current, iptr->isn_arg.string); 5007 smsg("%s%4d LOADENV %s", pfx, current, iptr->isn_arg.string);
4997 break; 5008 break;
4998 case ISN_LOADREG: 5009 case ISN_LOADREG:
4999 smsg("%s%4d LOADREG @%c", pfx, current, (int)(iptr->isn_arg.number)); 5010 smsg("%s%4d LOADREG @%c", pfx, current,
5011 (int)(iptr->isn_arg.number));
5000 break; 5012 break;
5001 5013
5002 case ISN_STORE: 5014 case ISN_STORE:
5003 if (iptr->isn_arg.number < 0) 5015 if (iptr->isn_arg.number < 0)
5004 smsg("%s%4d STORE arg[%lld]", pfx, current, 5016 smsg("%s%4d STORE arg[%lld]", pfx, current,
5005 iptr->isn_arg.number + STACK_FRAME_SIZE); 5017 iptr->isn_arg.number + STACK_FRAME_SIZE);
5006 else 5018 else
5007 smsg("%s%4d STORE $%lld", pfx, current, iptr->isn_arg.number); 5019 smsg("%s%4d STORE $%lld", pfx, current,
5020 iptr->isn_arg.number);
5008 break; 5021 break;
5009 case ISN_STOREOUTER: 5022 case ISN_STOREOUTER:
5010 { 5023 {
5011 if (iptr->isn_arg.number < 0) 5024 if (iptr->isn_arg.number < 0)
5012 smsg("%s%4d STOREOUTEr level %d arg[%d]", pfx, current, 5025 smsg("%s%4d STOREOUTEr level %d arg[%d]", pfx, current,
5046 iptr->isn_arg.loadstore.ls_name, si->sn_name); 5059 iptr->isn_arg.loadstore.ls_name, si->sn_name);
5047 } 5060 }
5048 break; 5061 break;
5049 case ISN_STORESCRIPT: 5062 case ISN_STORESCRIPT:
5050 { 5063 {
5051 scriptref_T *sref = iptr->isn_arg.script.scriptref; 5064 scriptref_T *sref = iptr->isn_arg.script.scriptref;
5052 scriptitem_T *si = SCRIPT_ITEM(sref->sref_sid); 5065 scriptitem_T *si = SCRIPT_ITEM(sref->sref_sid);
5053 svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data) 5066 svar_T *sv;
5054 + sref->sref_idx; 5067
5055 5068 sv = get_script_svar(sref, -1);
5056 smsg("%s%4d STORESCRIPT %s-%d in %s", pfx, current, 5069 if (sv == NULL)
5070 smsg("%s%4d STORESCRIPT [deleted] in %s",
5071 pfx, current, si->sn_name);
5072 else
5073 smsg("%s%4d STORESCRIPT %s-%d in %s", pfx, current,
5057 sv->sv_name, 5074 sv->sv_name,
5058 sref->sref_idx, 5075 sref->sref_idx,
5059 si->sn_name); 5076 si->sn_name);
5060 } 5077 }
5061 break; 5078 break;
5065 break; 5082 break;
5066 case ISN_STOREENV: 5083 case ISN_STOREENV:
5067 smsg("%s%4d STOREENV $%s", pfx, current, iptr->isn_arg.string); 5084 smsg("%s%4d STOREENV $%s", pfx, current, iptr->isn_arg.string);
5068 break; 5085 break;
5069 case ISN_STOREREG: 5086 case ISN_STOREREG:
5070 smsg("%s%4d STOREREG @%c", pfx, current, (int)iptr->isn_arg.number); 5087 smsg("%s%4d STOREREG @%c", pfx, current,
5088 (int)iptr->isn_arg.number);
5071 break; 5089 break;
5072 case ISN_STORENR: 5090 case ISN_STORENR:
5073 smsg("%s%4d STORE %lld in $%d", pfx, current, 5091 smsg("%s%4d STORE %lld in $%d", pfx, current,
5074 iptr->isn_arg.storenr.stnr_val, 5092 iptr->isn_arg.storenr.stnr_val,
5075 iptr->isn_arg.storenr.stnr_idx); 5093 iptr->isn_arg.storenr.stnr_idx);
5191 cdfunc_T *cdfunc = &iptr->isn_arg.dfunc; 5209 cdfunc_T *cdfunc = &iptr->isn_arg.dfunc;
5192 dfunc_T *df = ((dfunc_T *)def_functions.ga_data) 5210 dfunc_T *df = ((dfunc_T *)def_functions.ga_data)
5193 + cdfunc->cdf_idx; 5211 + cdfunc->cdf_idx;
5194 5212
5195 smsg("%s%4d DCALL %s(argc %d)", pfx, current, 5213 smsg("%s%4d DCALL %s(argc %d)", pfx, current,
5196 df->df_ufunc->uf_name_exp != NULL 5214 printable_func_name(df->df_ufunc),
5197 ? df->df_ufunc->uf_name_exp 5215 cdfunc->cdf_argcount);
5198 : df->df_ufunc->uf_name, cdfunc->cdf_argcount);
5199 } 5216 }
5200 break; 5217 break;
5201 case ISN_UCALL: 5218 case ISN_UCALL:
5202 { 5219 {
5203 cufunc_T *cufunc = &iptr->isn_arg.ufunc; 5220 cufunc_T *cufunc = &iptr->isn_arg.ufunc;
5660 if (ufunc->uf_def_status != UF_COMPILED) 5677 if (ufunc->uf_def_status != UF_COMPILED)
5661 { 5678 {
5662 semsg(_(e_function_is_not_compiled_str), eap->arg); 5679 semsg(_(e_function_is_not_compiled_str), eap->arg);
5663 return; 5680 return;
5664 } 5681 }
5665 if (ufunc->uf_name_exp != NULL) 5682 msg((char *)printable_func_name(ufunc));
5666 msg((char *)ufunc->uf_name_exp);
5667 else
5668 msg((char *)ufunc->uf_name);
5669 5683
5670 dfunc = ((dfunc_T *)def_functions.ga_data) + ufunc->uf_dfunc_idx; 5684 dfunc = ((dfunc_T *)def_functions.ga_data) + ufunc->uf_dfunc_idx;
5671 switch (compile_type) 5685 switch (compile_type)
5672 { 5686 {
5673 case CT_PROFILE: 5687 case CT_PROFILE: