Mercurial > vim
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: |