Mercurial > vim
comparison src/vim9script.c @ 26482:b115b552071f v8.2.3771
patch 8.2.3771: Vim9: accessing freed memory when checking type
Commit: https://github.com/vim/vim/commit/dd297bc11d2793ba61638972778c57f2da14e8b5
Author: Bram Moolenaar <Bram@vim.org>
Date: Fri Dec 10 10:37:38 2021 +0000
patch 8.2.3771: Vim9: accessing freed memory when checking type
Problem: Vim9: accessing freed memory when checking type.
Solution: Make a copy of a function type.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Fri, 10 Dec 2021 11:45:03 +0100 |
parents | 7351926fbe9e |
children | 4b23672d1f0e |
comparison
equal
deleted
inserted
replaced
26481:3e235c3b59ff | 26482:b115b552071f |
---|---|
266 int todo; | 266 int todo; |
267 hashtab_T *ht = &si->sn_all_vars.dv_hashtab; | 267 hashtab_T *ht = &si->sn_all_vars.dv_hashtab; |
268 hashitem_T *hi; | 268 hashitem_T *hi; |
269 sallvar_T *sav; | 269 sallvar_T *sav; |
270 sallvar_T *sav_next; | 270 sallvar_T *sav_next; |
271 int idx; | |
271 | 272 |
272 hash_lock(ht); | 273 hash_lock(ht); |
273 todo = (int)ht->ht_used; | 274 todo = (int)ht->ht_used; |
274 for (hi = ht->ht_array; todo > 0; ++hi) | 275 for (hi = ht->ht_array; todo > 0; ++hi) |
275 { | 276 { |
291 } | 292 } |
292 } | 293 } |
293 hash_clear(ht); | 294 hash_clear(ht); |
294 hash_init(ht); | 295 hash_init(ht); |
295 | 296 |
297 for (idx = 0; idx < si->sn_var_vals.ga_len; ++idx) | |
298 { | |
299 svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data) + idx; | |
300 | |
301 if (sv->sv_type_allocated) | |
302 free_type(sv->sv_type); | |
303 } | |
296 ga_clear(&si->sn_var_vals); | 304 ga_clear(&si->sn_var_vals); |
297 | 305 |
298 // existing commands using script variable indexes are no longer valid | 306 // existing commands using script variable indexes are no longer valid |
299 si->sn_script_seq = current_sctx.sc_seq; | 307 si->sn_script_seq = current_sctx.sc_seq; |
300 } | 308 } |
897 } | 905 } |
898 if (sv != NULL) | 906 if (sv != NULL) |
899 { | 907 { |
900 if (*type == NULL) | 908 if (*type == NULL) |
901 *type = typval2type(tv, get_copyID(), &si->sn_type_list, do_member); | 909 *type = typval2type(tv, get_copyID(), &si->sn_type_list, do_member); |
902 sv->sv_type = *type; | 910 if (sv->sv_type_allocated) |
911 free_type(sv->sv_type); | |
912 if (*type != NULL && ((*type)->tt_type == VAR_FUNC | |
913 || (*type)->tt_type == VAR_PARTIAL)) | |
914 { | |
915 // The type probably uses uf_type_list, which is cleared when the | |
916 // function is freed, but the script variable may keep the type. | |
917 // Make a copy to avoid using freed memory. | |
918 sv->sv_type = alloc_type(*type); | |
919 sv->sv_type_allocated = TRUE; | |
920 } | |
921 else | |
922 { | |
923 sv->sv_type = *type; | |
924 sv->sv_type_allocated = FALSE; | |
925 } | |
903 } | 926 } |
904 | 927 |
905 // let ex_export() know the export worked. | 928 // let ex_export() know the export worked. |
906 is_export = FALSE; | 929 is_export = FALSE; |
907 } | 930 } |