Skip to content

Commit f45dbe5

Browse files
committed
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
1 parent 6301b72 commit f45dbe5

File tree

1 file changed

+11
-6
lines changed

1 file changed

+11
-6
lines changed

crates/bevy_ecs/src/storage/blob_vec.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -199,13 +199,11 @@ impl BlobVec {
199199
impl Drop for BlobVec {
200200
fn drop(&mut self) {
201201
self.clear();
202-
if self.item_layout.size() > 0 {
202+
let array_layout =
203+
array_layout(&self.item_layout, self.capacity).expect("array layout should be valid");
204+
if array_layout.size() > 0 {
203205
unsafe {
204-
std::alloc::dealloc(
205-
self.get_ptr().as_ptr(),
206-
array_layout(&self.item_layout, self.capacity)
207-
.expect("array layout should be valid"),
208-
);
206+
std::alloc::dealloc(self.get_ptr().as_ptr(), array_layout);
209207
std::alloc::dealloc(self.swap_scratch.as_ptr(), self.item_layout);
210208
}
211209
}
@@ -388,4 +386,11 @@ mod tests {
388386

389387
assert_eq!(*drop_counter.borrow(), 6);
390388
}
389+
390+
#[test]
391+
fn blob_vec_drop_empty_capacity() {
392+
let item_layout = Layout::new::<Foo>();
393+
let drop = TypeInfo::drop_ptr::<Foo>;
394+
let _ = BlobVec::new(item_layout, drop, 0);
395+
}
391396
}

0 commit comments

Comments
 (0)