From f45dbe5bac0bb5923a38ea49b2581915b0db3953 Mon Sep 17 00:00:00 2001 From: thebluefish Date: Wed, 2 Jun 2021 19:08:39 +0000 Subject: [PATCH] Fixes dropping empty BlobVec (#2295) When dropping the data, we originally only checked the size of an individual item instead of the size of the allocation. However with a capacity of 0, we attempt to deallocate a pointer which was not the result of allocation. That is, an item of `Layout { size_: 8, align_: 8 }` produces an array of `Layout { size_: 0, align_: 8 }` when `capacity = 0`. Fixes #2294 --- crates/bevy_ecs/src/storage/blob_vec.rs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/crates/bevy_ecs/src/storage/blob_vec.rs b/crates/bevy_ecs/src/storage/blob_vec.rs index 7469355cb7..d724728c17 100644 --- a/crates/bevy_ecs/src/storage/blob_vec.rs +++ b/crates/bevy_ecs/src/storage/blob_vec.rs @@ -199,13 +199,11 @@ impl BlobVec { impl Drop for BlobVec { fn drop(&mut self) { self.clear(); - if self.item_layout.size() > 0 { + let array_layout = + array_layout(&self.item_layout, self.capacity).expect("array layout should be valid"); + if array_layout.size() > 0 { unsafe { - std::alloc::dealloc( - self.get_ptr().as_ptr(), - array_layout(&self.item_layout, self.capacity) - .expect("array layout should be valid"), - ); + std::alloc::dealloc(self.get_ptr().as_ptr(), array_layout); std::alloc::dealloc(self.swap_scratch.as_ptr(), self.item_layout); } } @@ -388,4 +386,11 @@ mod tests { assert_eq!(*drop_counter.borrow(), 6); } + + #[test] + fn blob_vec_drop_empty_capacity() { + let item_layout = Layout::new::(); + let drop = TypeInfo::drop_ptr::; + let _ = BlobVec::new(item_layout, drop, 0); + } }