From 528cbc4879ceab332d509e4959fcea8baa7e8b92 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 8 Mar 2020 16:43:03 +0100 Subject: [PATCH] fix memory leak when vec::IntoIter panics during drop --- src/liballoc/vec.rs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 61416f2b906..913e261ef12 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -2626,13 +2626,21 @@ impl Clone for IntoIter { #[stable(feature = "rust1", since = "1.0.0")] unsafe impl<#[may_dangle] T> Drop for IntoIter { fn drop(&mut self) { - // destroy the remaining elements - unsafe { - ptr::drop_in_place(self.as_mut_slice()); + struct DropGuard<'a, T>(&'a mut IntoIter); + + impl Drop for DropGuard<'_, T> { + fn drop(&mut self) { + // RawVec handles deallocation + let _ = unsafe { RawVec::from_raw_parts(self.0.buf.as_ptr(), self.0.cap) }; + } } - // RawVec handles deallocation - let _ = unsafe { RawVec::from_raw_parts(self.buf.as_ptr(), self.cap) }; + let guard = DropGuard(self); + // destroy the remaining elements + unsafe { + ptr::drop_in_place(guard.0.as_mut_slice()); + } + // now `guard` will be dropped and do the rest } }