comparison src/list.c @ 25784:8dfcee931c6c v8.2.3427

patch 8.2.3427: double free when list is copied Commit: https://github.com/vim/vim/commit/b3bf33a7b227df871834e816c4ce4b2706b56bea Author: Bram Moolenaar <Bram@vim.org> Date: Sat Sep 11 20:20:38 2021 +0200 patch 8.2.3427: double free when list is copied Problem: Double free when list is copied. Solution: Allocate the type when making a copy. (closes https://github.com/vim/vim/issues/8862) Clear the type for flattennew(). Avoid a memory leak when flattennew() fails.
author Bram Moolenaar <Bram@vim.org>
date Sat, 11 Sep 2021 20:30:04 +0200
parents 9edad9a8cca6
children 14954a7e7c6d
comparison
equal deleted inserted replaced
25783:aee42bda9b8a 25784:8dfcee931c6c
950 { 950 {
951 listitem_T *next = item->li_next; 951 listitem_T *next = item->li_next;
952 952
953 vimlist_remove(list, item, item); 953 vimlist_remove(list, item, item);
954 if (list_extend(list, item->li_tv.vval.v_list, next) == FAIL) 954 if (list_extend(list, item->li_tv.vval.v_list, next) == FAIL)
955 {
956 list_free_item(list, item);
955 return; 957 return;
958 }
956 clear_tv(&item->li_tv); 959 clear_tv(&item->li_tv);
957 tofree = item; 960 tofree = item;
958 961
959 if (item->li_prev == NULL) 962 if (item->li_prev == NULL)
960 item = list->lv_first; 963 item = list->lv_first;
1021 { 1024 {
1022 l = list_copy(l, TRUE, get_copyID()); 1025 l = list_copy(l, TRUE, get_copyID());
1023 rettv->vval.v_list = l; 1026 rettv->vval.v_list = l;
1024 if (l == NULL) 1027 if (l == NULL)
1025 return; 1028 return;
1029 // The type will change.
1030 free_type(l->lv_type);
1031 l->lv_type = NULL;
1026 } 1032 }
1027 else 1033 else
1028 { 1034 {
1029 if (value_check_lock(l->lv_lock, 1035 if (value_check_lock(l->lv_lock,
1030 (char_u *)N_("flatten() argument"), TRUE)) 1036 (char_u *)N_("flatten() argument"), TRUE))
1215 return NULL; 1221 return NULL;
1216 1222
1217 copy = list_alloc(); 1223 copy = list_alloc();
1218 if (copy != NULL) 1224 if (copy != NULL)
1219 { 1225 {
1220 copy->lv_type = orig->lv_type; 1226 copy->lv_type = alloc_type(orig->lv_type);
1221 if (copyID != 0) 1227 if (copyID != 0)
1222 { 1228 {
1223 // Do this before adding the items, because one of the items may 1229 // Do this before adding the items, because one of the items may
1224 // refer back to this list. 1230 // refer back to this list.
1225 orig->lv_copyID = copyID; 1231 orig->lv_copyID = copyID;