diff options
| author | The 8472 <git@infinite-source.de> | 2023-04-29 12:34:28 +0200 |
|---|---|---|
| committer | The 8472 <git@infinite-source.de> | 2023-09-03 19:59:47 +0200 |
| commit | 6e4f98c987f196ed27a3eae9ebb019ec89759f6c (patch) | |
| tree | eb5d54ba0779de07257087cfb718ee311690859e /library/alloc/src/vec | |
| parent | 3ca6bb0b44c3e65dab07e12aec9efb277dc206f9 (diff) | |
| download | rust-6e4f98c987f196ed27a3eae9ebb019ec89759f6c.tar.gz rust-6e4f98c987f196ed27a3eae9ebb019ec89759f6c.zip | |
don't leak items if alloc::shrink panics
Diffstat (limited to 'library/alloc/src/vec')
| -rw-r--r-- | library/alloc/src/vec/in_place_collect.rs | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/library/alloc/src/vec/in_place_collect.rs b/library/alloc/src/vec/in_place_collect.rs index d174074902a..20ecc50c4b6 100644 --- a/library/alloc/src/vec/in_place_collect.rs +++ b/library/alloc/src/vec/in_place_collect.rs @@ -225,16 +225,18 @@ where } // The ownership of the allocation and the new `T` values is temporarily moved into `dst_guard`. - // This is safe because `forget_allocation_drop_remaining` immediately forgets the allocation + // This is safe because + // * `forget_allocation_drop_remaining` immediately forgets the allocation // before any panic can occur in order to avoid any double free, and then proceeds to drop // any remaining values at the tail of the source. + // * the shrink either panics without invalidating the allocation, aborts or + // succeeds. In the last case we disarm the guard. // // Note: This access to the source wouldn't be allowed by the TrustedRandomIteratorNoCoerce // contract (used by SpecInPlaceCollect below). But see the "O(1) collect" section in the // module documentation why this is ok anyway. let dst_guard = InPlaceDstBufDrop { ptr: dst_buf, len, cap: dst_cap }; src.forget_allocation_drop_remaining(); - mem::forget(dst_guard); // Adjust the allocation size if the source had a capacity in bytes that wasn't a multiple // of the destination type size. @@ -256,6 +258,8 @@ where } } + mem::forget(dst_guard); + let vec = unsafe { Vec::from_raw_parts(dst_buf, len, dst_cap) }; vec |
