Mercurial > vim
comparison 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 |
comparison
equal
deleted
inserted
replaced
23265:684de8fd484a | 23266:00f7cd9b6033 |
---|---|
5902 if (r == FAIL) | 5902 if (r == FAIL) |
5903 goto theend; | 5903 goto theend; |
5904 | 5904 |
5905 if (type == &t_any) | 5905 if (type == &t_any) |
5906 { | 5906 { |
5907 type_T *idx_type = ((type_T **)stack->ga_data)[ | 5907 // Index on variable of unknown type: check at runtime. |
5908 stack->ga_len - 1]; | 5908 dest_type = VAR_ANY; |
5909 // Index on variable of unknown type: guess the type from the | 5909 } |
5910 // index type: number is dict, otherwise dict. | 5910 else |
5911 // TODO: should do the assignment at runtime | 5911 { |
5912 if (idx_type->tt_type == VAR_NUMBER) | 5912 dest_type = type->tt_type; |
5913 type = &t_list_any; | 5913 if (dest_type == VAR_DICT |
5914 else | 5914 && may_generate_2STRING(-1, cctx) == FAIL) |
5915 type = &t_dict_any; | 5915 goto theend; |
5916 } | 5916 if (dest_type == VAR_LIST |
5917 dest_type = type->tt_type; | 5917 && ((type_T **)stack->ga_data)[stack->ga_len - 1]->tt_type |
5918 if (dest_type == VAR_DICT | |
5919 && may_generate_2STRING(-1, cctx) == FAIL) | |
5920 goto theend; | |
5921 if (dest_type == VAR_LIST | |
5922 && ((type_T **)stack->ga_data)[stack->ga_len - 1]->tt_type | |
5923 != VAR_NUMBER) | 5918 != VAR_NUMBER) |
5924 { | 5919 { |
5925 emsg(_(e_number_exp)); | 5920 emsg(_(e_number_exp)); |
5926 goto theend; | 5921 goto theend; |
5922 } | |
5927 } | 5923 } |
5928 | 5924 |
5929 // Load the dict or list. On the stack we then have: | 5925 // Load the dict or list. On the stack we then have: |
5930 // - value | 5926 // - value |
5931 // - index | 5927 // - index |
5954 goto theend; | 5950 goto theend; |
5955 } | 5951 } |
5956 else | 5952 else |
5957 generate_loadvar(cctx, dest, name, lvar, type); | 5953 generate_loadvar(cctx, dest, name, lvar, type); |
5958 | 5954 |
5959 if (dest_type == VAR_LIST) | 5955 if (dest_type == VAR_LIST || dest_type == VAR_DICT |
5960 { | 5956 || dest_type == VAR_ANY) |
5961 if (generate_instr_drop(cctx, ISN_STORELIST, 3) == FAIL) | 5957 { |
5958 isn_T *isn = generate_instr_drop(cctx, ISN_STOREINDEX, 3); | |
5959 | |
5960 if (isn == NULL) | |
5962 goto theend; | 5961 goto theend; |
5963 } | 5962 isn->isn_arg.vartype = dest_type; |
5964 else if (dest_type == VAR_DICT) | |
5965 { | |
5966 if (generate_instr_drop(cctx, ISN_STOREDICT, 3) == FAIL) | |
5967 goto theend; | |
5968 } | 5963 } |
5969 else | 5964 else |
5970 { | 5965 { |
5971 emsg(_(e_indexable_type_required)); | 5966 emsg(_(e_indexable_type_required)); |
5972 goto theend; | 5967 goto theend; |
8192 case ISN_PUT: | 8187 case ISN_PUT: |
8193 case ISN_RETURN: | 8188 case ISN_RETURN: |
8194 case ISN_SHUFFLE: | 8189 case ISN_SHUFFLE: |
8195 case ISN_SLICE: | 8190 case ISN_SLICE: |
8196 case ISN_STORE: | 8191 case ISN_STORE: |
8197 case ISN_STOREDICT: | 8192 case ISN_STOREINDEX: |
8198 case ISN_STORELIST: | |
8199 case ISN_STORENR: | 8193 case ISN_STORENR: |
8200 case ISN_STOREOUTER: | 8194 case ISN_STOREOUTER: |
8201 case ISN_STOREREG: | 8195 case ISN_STOREREG: |
8202 case ISN_STORESCRIPT: | 8196 case ISN_STORESCRIPT: |
8203 case ISN_STOREV: | 8197 case ISN_STOREV: |