diff options
Diffstat (limited to 'dev-lang/rust/files')
-rw-r--r-- | dev-lang/rust/files/1.51.0-CVE-2020-36323.patch | 175 | ||||
-rw-r--r-- | dev-lang/rust/files/1.51.0-CVE-2021-28876.patch | 39 | ||||
-rw-r--r-- | dev-lang/rust/files/1.51.0-CVE-2021-28878.patch | 112 | ||||
-rw-r--r-- | dev-lang/rust/files/1.51.0-CVE-2021-28879.patch | 84 | ||||
-rw-r--r-- | dev-lang/rust/files/1.51.0-CVE-2021-31162.patch | 195 |
5 files changed, 605 insertions, 0 deletions
diff --git a/dev-lang/rust/files/1.51.0-CVE-2020-36323.patch b/dev-lang/rust/files/1.51.0-CVE-2020-36323.patch new file mode 100644 index 000000000000..b4f2215cc236 --- /dev/null +++ b/dev-lang/rust/files/1.51.0-CVE-2020-36323.patch @@ -0,0 +1,175 @@ +From 6d43225bfb08ec91f7476b76c7fec632c4a096ef Mon Sep 17 00:00:00 2001 +From: Yechan Bae <yechan@gatech.edu> +Date: Wed, 3 Feb 2021 16:36:33 -0500 +Subject: [PATCH 1/2] Fixes #80335 + +--- + library/alloc/src/str.rs | 42 ++++++++++++++++++++++---------------- + library/alloc/tests/str.rs | 30 +++++++++++++++++++++++++++ + 2 files changed, 54 insertions(+), 18 deletions(-) + +diff --git a/library/alloc/src/str.rs b/library/alloc/src/str.rs +index 70e0c7dba5eab..a7584c6b65100 100644 +--- a/library/alloc/src/str.rs ++++ b/library/alloc/src/str.rs +@@ -90,8 +90,8 @@ impl<S: Borrow<str>> Join<&str> for [S] { + } + } + +-macro_rules! spezialize_for_lengths { +- ($separator:expr, $target:expr, $iter:expr; $($num:expr),*) => { ++macro_rules! specialize_for_lengths { ++ ($separator:expr, $target:expr, $iter:expr; $($num:expr),*) => {{ + let mut target = $target; + let iter = $iter; + let sep_bytes = $separator; +@@ -102,7 +102,8 @@ macro_rules! spezialize_for_lengths { + $num => { + for s in iter { + copy_slice_and_advance!(target, sep_bytes); +- copy_slice_and_advance!(target, s.borrow().as_ref()); ++ let content_bytes = s.borrow().as_ref(); ++ copy_slice_and_advance!(target, content_bytes); + } + }, + )* +@@ -110,11 +111,13 @@ macro_rules! spezialize_for_lengths { + // arbitrary non-zero size fallback + for s in iter { + copy_slice_and_advance!(target, sep_bytes); +- copy_slice_and_advance!(target, s.borrow().as_ref()); ++ let content_bytes = s.borrow().as_ref(); ++ copy_slice_and_advance!(target, content_bytes); + } + } + } +- }; ++ target ++ }} + } + + macro_rules! copy_slice_and_advance { +@@ -153,7 +156,7 @@ where + // if the `len` calculation overflows, we'll panic + // we would have run out of memory anyway and the rest of the function requires + // the entire Vec pre-allocated for safety +- let len = sep_len ++ let reserved_len = sep_len + .checked_mul(iter.len()) + .and_then(|n| { + slice.iter().map(|s| s.borrow().as_ref().len()).try_fold(n, usize::checked_add) +@@ -161,22 +164,25 @@ where + .expect("attempt to join into collection with len > usize::MAX"); + + // crucial for safety +- let mut result = Vec::with_capacity(len); +- assert!(result.capacity() >= len); ++ let mut result = Vec::with_capacity(reserved_len); ++ debug_assert!(result.capacity() >= reserved_len); + + result.extend_from_slice(first.borrow().as_ref()); + + unsafe { +- { +- let pos = result.len(); +- let target = result.get_unchecked_mut(pos..len); +- +- // copy separator and slices over without bounds checks +- // generate loops with hardcoded offsets for small separators +- // massive improvements possible (~ x2) +- spezialize_for_lengths!(sep, target, iter; 0, 1, 2, 3, 4); +- } +- result.set_len(len); ++ let pos = result.len(); ++ let target = result.get_unchecked_mut(pos..reserved_len); ++ ++ // copy separator and slices over without bounds checks ++ // generate loops with hardcoded offsets for small separators ++ // massive improvements possible (~ x2) ++ let remain = specialize_for_lengths!(sep, target, iter; 0, 1, 2, 3, 4); ++ ++ // issue #80335: A weird borrow implementation can return different ++ // slices for the length calculation and the actual copy, so ++ // `remain.len()` might be non-zero. ++ let result_len = reserved_len - remain.len(); ++ result.set_len(result_len); + } + result + } +diff --git a/library/alloc/tests/str.rs b/library/alloc/tests/str.rs +index 604835e6cc4a6..6df8d8c2f354f 100644 +--- a/library/alloc/tests/str.rs ++++ b/library/alloc/tests/str.rs +@@ -160,6 +160,36 @@ fn test_join_for_different_lengths_with_long_separator() { + test_join!("~~~~~a~~~~~bc", ["", "a", "bc"], "~~~~~"); + } + ++#[test] ++fn test_join_isue_80335() { ++ use core::{borrow::Borrow, cell::Cell}; ++ ++ struct WeirdBorrow { ++ state: Cell<bool>, ++ } ++ ++ impl Default for WeirdBorrow { ++ fn default() -> Self { ++ WeirdBorrow { state: Cell::new(false) } ++ } ++ } ++ ++ impl Borrow<str> for WeirdBorrow { ++ fn borrow(&self) -> &str { ++ let state = self.state.get(); ++ if state { ++ "0" ++ } else { ++ self.state.set(true); ++ "123456" ++ } ++ } ++ } ++ ++ let arr: [WeirdBorrow; 3] = Default::default(); ++ test_join!("0-0-0", arr, "-"); ++} ++ + #[test] + #[cfg_attr(miri, ignore)] // Miri is too slow + fn test_unsafe_slice() { + +From 26a62701e42d10c03ce5f2f911e7d5edeefa2f0f Mon Sep 17 00:00:00 2001 +From: Yechan Bae <yechan@gatech.edu> +Date: Sat, 20 Mar 2021 13:42:54 -0400 +Subject: [PATCH 2/2] Update the comment + +--- + library/alloc/src/str.rs | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/library/alloc/src/str.rs b/library/alloc/src/str.rs +index a7584c6b65100..4d1e876457b8e 100644 +--- a/library/alloc/src/str.rs ++++ b/library/alloc/src/str.rs +@@ -163,7 +163,7 @@ where + }) + .expect("attempt to join into collection with len > usize::MAX"); + +- // crucial for safety ++ // prepare an uninitialized buffer + let mut result = Vec::with_capacity(reserved_len); + debug_assert!(result.capacity() >= reserved_len); + +@@ -178,9 +178,9 @@ where + // massive improvements possible (~ x2) + let remain = specialize_for_lengths!(sep, target, iter; 0, 1, 2, 3, 4); + +- // issue #80335: A weird borrow implementation can return different +- // slices for the length calculation and the actual copy, so +- // `remain.len()` might be non-zero. ++ // A weird borrow implementation may return different ++ // slices for the length calculation and the actual copy. ++ // Make sure we don't expose uninitialized bytes to the caller. + let result_len = reserved_len - remain.len(); + result.set_len(result_len); + } diff --git a/dev-lang/rust/files/1.51.0-CVE-2021-28876.patch b/dev-lang/rust/files/1.51.0-CVE-2021-28876.patch new file mode 100644 index 000000000000..3a0af0241435 --- /dev/null +++ b/dev-lang/rust/files/1.51.0-CVE-2021-28876.patch @@ -0,0 +1,39 @@ +From 86a4b27475aab52b998c15f5758540697cc9cff0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com> +Date: Thu, 4 Feb 2021 10:23:01 +0200 +Subject: [PATCH] Increment `self.index` before calling + `Iterator::self.a.__iterator_get_unchecked` in `Zip` `TrustedRandomAccess` + specialization + +Otherwise if `Iterator::self.a.__iterator_get_unchecked` panics the +index would not have been incremented yet and another call to +`Iterator::next` would read from the same index again, which is not +allowed according to the API contract of `TrustedRandomAccess` for +`!Clone`. + +Fixes https://github.com/rust-lang/rust/issues/81740 +--- + library/core/src/iter/adapters/zip.rs | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/library/core/src/iter/adapters/zip.rs b/library/core/src/iter/adapters/zip.rs +index 98b8dca961407..9f98353452006 100644 +--- a/library/core/src/iter/adapters/zip.rs ++++ b/library/core/src/iter/adapters/zip.rs +@@ -198,12 +198,13 @@ where + Some((self.a.__iterator_get_unchecked(i), self.b.__iterator_get_unchecked(i))) + } + } else if A::may_have_side_effect() && self.index < self.a.size() { ++ let i = self.index; ++ self.index += 1; + // match the base implementation's potential side effects +- // SAFETY: we just checked that `self.index` < `self.a.len()` ++ // SAFETY: we just checked that `i` < `self.a.len()` + unsafe { +- self.a.__iterator_get_unchecked(self.index); ++ self.a.__iterator_get_unchecked(i); + } +- self.index += 1; + None + } else { + None diff --git a/dev-lang/rust/files/1.51.0-CVE-2021-28878.patch b/dev-lang/rust/files/1.51.0-CVE-2021-28878.patch new file mode 100644 index 000000000000..f319ab5e8c44 --- /dev/null +++ b/dev-lang/rust/files/1.51.0-CVE-2021-28878.patch @@ -0,0 +1,112 @@ +From 2371914a05f8f2763dffe6e2511d0870bcd6b461 Mon Sep 17 00:00:00 2001 +From: Giacomo Stevanato <giaco.stevanato@gmail.com> +Date: Wed, 3 Mar 2021 21:09:01 +0100 +Subject: [PATCH 1/2] Prevent Zip specialization from calling + __iterator_get_unchecked twice with the same index after calling next_back + +--- + library/core/src/iter/adapters/zip.rs | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/library/core/src/iter/adapters/zip.rs b/library/core/src/iter/adapters/zip.rs +index 817fc2a51e981..ea7a809c6badb 100644 +--- a/library/core/src/iter/adapters/zip.rs ++++ b/library/core/src/iter/adapters/zip.rs +@@ -13,9 +13,10 @@ use crate::iter::{InPlaceIterable, SourceIter, TrustedLen}; + pub struct Zip<A, B> { + a: A, + b: B, +- // index and len are only used by the specialized version of zip ++ // index, len and a_len are only used by the specialized version of zip + index: usize, + len: usize, ++ a_len: usize, + } + impl<A: Iterator, B: Iterator> Zip<A, B> { + pub(in crate::iter) fn new(a: A, b: B) -> Zip<A, B> { +@@ -110,6 +111,7 @@ where + b, + index: 0, // unused + len: 0, // unused ++ a_len: 0, // unused + } + } + +@@ -184,8 +186,9 @@ where + B: TrustedRandomAccess + Iterator, + { + fn new(a: A, b: B) -> Self { +- let len = cmp::min(a.size(), b.size()); +- Zip { a, b, index: 0, len } ++ let a_len = a.size(); ++ let len = cmp::min(a_len, b.size()); ++ Zip { a, b, index: 0, len, a_len } + } + + #[inline] +@@ -197,7 +200,7 @@ where + unsafe { + Some((self.a.__iterator_get_unchecked(i), self.b.__iterator_get_unchecked(i))) + } +- } else if A::MAY_HAVE_SIDE_EFFECT && self.index < self.a.size() { ++ } else if A::MAY_HAVE_SIDE_EFFECT && self.index < self.a_len { + let i = self.index; + self.index += 1; + self.len += 1; +@@ -262,6 +265,7 @@ where + for _ in 0..sz_a - self.len { + self.a.next_back(); + } ++ self.a_len = self.len; + } + let sz_b = self.b.size(); + if B::MAY_HAVE_SIDE_EFFECT && sz_b > self.len { +@@ -273,6 +277,7 @@ where + } + if self.index < self.len { + self.len -= 1; ++ self.a_len -= 1; + let i = self.len; + // SAFETY: `i` is smaller than the previous value of `self.len`, + // which is also smaller than or equal to `self.a.len()` and `self.b.len()` + +From c1bfb9a78db6d481be1d03355672712c766e20b0 Mon Sep 17 00:00:00 2001 +From: Giacomo Stevanato <giaco.stevanato@gmail.com> +Date: Fri, 19 Feb 2021 15:25:09 +0100 +Subject: [PATCH 2/2] Add relevant test + +--- + library/core/tests/iter/adapters/zip.rs | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +diff --git a/library/core/tests/iter/adapters/zip.rs b/library/core/tests/iter/adapters/zip.rs +index a597710392952..000c15f72c886 100644 +--- a/library/core/tests/iter/adapters/zip.rs ++++ b/library/core/tests/iter/adapters/zip.rs +@@ -265,3 +265,26 @@ fn test_issue_82282() { + panic!(); + } + } ++ ++#[test] ++fn test_issue_82291() { ++ use std::cell::Cell; ++ ++ let mut v1 = [()]; ++ let v2 = [()]; ++ ++ let called = Cell::new(0); ++ ++ let mut zip = v1 ++ .iter_mut() ++ .map(|r| { ++ called.set(called.get() + 1); ++ r ++ }) ++ .zip(&v2); ++ ++ zip.next_back(); ++ assert_eq!(called.get(), 1); ++ zip.next(); ++ assert_eq!(called.get(), 1); ++} diff --git a/dev-lang/rust/files/1.51.0-CVE-2021-28879.patch b/dev-lang/rust/files/1.51.0-CVE-2021-28879.patch new file mode 100644 index 000000000000..3407a2ddf2f3 --- /dev/null +++ b/dev-lang/rust/files/1.51.0-CVE-2021-28879.patch @@ -0,0 +1,84 @@ +From 66a260617a88ed1ad55a46f03c5a90d5ad3004d3 Mon Sep 17 00:00:00 2001 +From: Giacomo Stevanato <giaco.stevanato@gmail.com> +Date: Fri, 19 Feb 2021 12:15:37 +0100 +Subject: [PATCH 1/3] Increment self.len in specialized ZipImpl to avoid + underflow in size_hint + +--- + library/core/src/iter/adapters/zip.rs | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/library/core/src/iter/adapters/zip.rs b/library/core/src/iter/adapters/zip.rs +index 9d0f4e3618fc5..ce48016afcd50 100644 +--- a/library/core/src/iter/adapters/zip.rs ++++ b/library/core/src/iter/adapters/zip.rs +@@ -200,6 +200,7 @@ where + } else if A::MAY_HAVE_SIDE_EFFECT && self.index < self.a.size() { + let i = self.index; + self.index += 1; ++ self.len += 1; + // match the base implementation's potential side effects + // SAFETY: we just checked that `i` < `self.a.len()` + unsafe { + +From 8b9ac4d4155c74db5b317046033ab9c05a09e351 Mon Sep 17 00:00:00 2001 +From: Giacomo Stevanato <giaco.stevanato@gmail.com> +Date: Fri, 19 Feb 2021 12:16:12 +0100 +Subject: [PATCH 2/3] Add test for underflow in specialized Zip's size_hint + +--- + library/core/tests/iter/adapters/zip.rs | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/library/core/tests/iter/adapters/zip.rs b/library/core/tests/iter/adapters/zip.rs +index 1fce0951e365e..a597710392952 100644 +--- a/library/core/tests/iter/adapters/zip.rs ++++ b/library/core/tests/iter/adapters/zip.rs +@@ -245,3 +245,23 @@ fn test_double_ended_zip() { + assert_eq!(it.next_back(), Some((3, 3))); + assert_eq!(it.next(), None); + } ++ ++#[test] ++fn test_issue_82282() { ++ fn overflowed_zip(arr: &[i32]) -> impl Iterator<Item = (i32, &())> { ++ static UNIT_EMPTY_ARR: [(); 0] = []; ++ ++ let mapped = arr.into_iter().map(|i| *i); ++ let mut zipped = mapped.zip(UNIT_EMPTY_ARR.iter()); ++ zipped.next(); ++ zipped ++ } ++ ++ let arr = [1, 2, 3]; ++ let zip = overflowed_zip(&arr).zip(overflowed_zip(&arr)); ++ ++ assert_eq!(zip.size_hint(), (0, Some(0))); ++ for _ in zip { ++ panic!(); ++ } ++} + +From aeb4ea739efb70e0002a4a9c4c7b8027dd0620b3 Mon Sep 17 00:00:00 2001 +From: Giacomo Stevanato <giaco.stevanato@gmail.com> +Date: Fri, 19 Feb 2021 12:17:48 +0100 +Subject: [PATCH 3/3] Remove useless comparison since now self.index <= + self.len is an invariant + +--- + library/core/src/iter/adapters/zip.rs | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/library/core/src/iter/adapters/zip.rs b/library/core/src/iter/adapters/zip.rs +index ce48016afcd50..817fc2a51e981 100644 +--- a/library/core/src/iter/adapters/zip.rs ++++ b/library/core/src/iter/adapters/zip.rs +@@ -259,7 +259,7 @@ where + if sz_a != sz_b { + let sz_a = self.a.size(); + if A::MAY_HAVE_SIDE_EFFECT && sz_a > self.len { +- for _ in 0..sz_a - cmp::max(self.len, self.index) { ++ for _ in 0..sz_a - self.len { + self.a.next_back(); + } + } diff --git a/dev-lang/rust/files/1.51.0-CVE-2021-31162.patch b/dev-lang/rust/files/1.51.0-CVE-2021-31162.patch new file mode 100644 index 000000000000..fd9165ea3c5e --- /dev/null +++ b/dev-lang/rust/files/1.51.0-CVE-2021-31162.patch @@ -0,0 +1,195 @@ +From fa89c0fbcfa8f4d44f153b1195ec5a305540ffc4 Mon Sep 17 00:00:00 2001 +From: The8472 <git@infinite-source.de> +Date: Mon, 29 Mar 2021 04:22:34 +0200 +Subject: [PATCH 1/3] add testcase for double-drop during Vec in-place + collection + +--- + library/alloc/tests/vec.rs | 38 +++++++++++++++++++++++++++++++++++++- + 1 file changed, 37 insertions(+), 1 deletion(-) + +diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs +index c142536cd2dfb..b926c697d58ab 100644 +--- a/library/alloc/tests/vec.rs ++++ b/library/alloc/tests/vec.rs +@@ -1027,7 +1027,7 @@ fn test_from_iter_specialization_head_tail_drop() { + } + + #[test] +-fn test_from_iter_specialization_panic_drop() { ++fn test_from_iter_specialization_panic_during_iteration_drops() { + let drop_count: Vec<_> = (0..=2).map(|_| Rc::new(())).collect(); + let src: Vec<_> = drop_count.iter().cloned().collect(); + let iter = src.into_iter(); +@@ -1050,6 +1050,42 @@ fn test_from_iter_specialization_panic_drop() { + ); + } + ++#[test] ++fn test_from_iter_specialization_panic_during_drop_leaks() { ++ static mut DROP_COUNTER: usize = 0; ++ ++ #[derive(Debug)] ++ enum Droppable { ++ DroppedTwice(Box<i32>), ++ PanicOnDrop, ++ } ++ ++ impl Drop for Droppable { ++ fn drop(&mut self) { ++ match self { ++ Droppable::DroppedTwice(_) => { ++ unsafe { ++ DROP_COUNTER += 1; ++ } ++ println!("Dropping!") ++ } ++ Droppable::PanicOnDrop => { ++ if !std::thread::panicking() { ++ panic!(); ++ } ++ } ++ } ++ } ++ } ++ ++ let _ = std::panic::catch_unwind(AssertUnwindSafe(|| { ++ let v = vec![Droppable::DroppedTwice(Box::new(123)), Droppable::PanicOnDrop]; ++ let _ = v.into_iter().take(0).collect::<Vec<_>>(); ++ })); ++ ++ assert_eq!(unsafe { DROP_COUNTER }, 1); ++} ++ + #[test] + fn test_cow_from() { + let borrowed: &[_] = &["borrowed", "(slice)"]; + +From 421f5d282a51e130d3ca7c4524d8ad6753437da9 Mon Sep 17 00:00:00 2001 +From: The8472 <git@infinite-source.de> +Date: Mon, 29 Mar 2021 04:22:48 +0200 +Subject: [PATCH 2/3] fix double-drop in in-place collect specialization + +--- + library/alloc/src/vec/into_iter.rs | 27 ++++++++++++++------- + library/alloc/src/vec/source_iter_marker.rs | 4 +-- + 2 files changed, 20 insertions(+), 11 deletions(-) + +diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs +index bcbdffabc7fbe..324e894bafd23 100644 +--- a/library/alloc/src/vec/into_iter.rs ++++ b/library/alloc/src/vec/into_iter.rs +@@ -85,20 +85,29 @@ impl<T, A: Allocator> IntoIter<T, A> { + ptr::slice_from_raw_parts_mut(self.ptr as *mut T, self.len()) + } + +- pub(super) fn drop_remaining(&mut self) { +- unsafe { +- ptr::drop_in_place(self.as_mut_slice()); +- } +- self.ptr = self.end; +- } ++ /// Drops remaining elements and relinquishes the backing allocation. ++ /// ++ /// This is roughly equivalent to the following, but more efficient ++ /// ++ /// ``` ++ /// # let mut into_iter = Vec::<u8>::with_capacity(10).into_iter(); ++ /// (&mut into_iter).for_each(core::mem::drop); ++ /// unsafe { core::ptr::write(&mut into_iter, Vec::new().into_iter()); } ++ /// ``` ++ pub(super) fn forget_allocation_drop_remaining(&mut self) { ++ let remaining = self.as_raw_mut_slice(); + +- /// Relinquishes the backing allocation, equivalent to +- /// `ptr::write(&mut self, Vec::new().into_iter())` +- pub(super) fn forget_allocation(&mut self) { ++ // overwrite the individual fields instead of creating a new ++ // struct and then overwriting &mut self. ++ // this creates less assembly + self.cap = 0; + self.buf = unsafe { NonNull::new_unchecked(RawVec::NEW.ptr()) }; + self.ptr = self.buf.as_ptr(); + self.end = self.buf.as_ptr(); ++ ++ unsafe { ++ ptr::drop_in_place(remaining); ++ } + } + } + +diff --git a/library/alloc/src/vec/source_iter_marker.rs b/library/alloc/src/vec/source_iter_marker.rs +index 50882fc17673e..e857d284d3ab6 100644 +--- a/library/alloc/src/vec/source_iter_marker.rs ++++ b/library/alloc/src/vec/source_iter_marker.rs +@@ -69,9 +69,9 @@ where + } + + // drop any remaining values at the tail of the source +- src.drop_remaining(); + // but prevent drop of the allocation itself once IntoIter goes out of scope +- src.forget_allocation(); ++ // if the drop panics then we also leak any elements collected into dst_buf ++ src.forget_allocation_drop_remaining(); + + let vec = unsafe { Vec::from_raw_parts(dst_buf, len, cap) }; + + +From 328a5e040780984c60dde2db300dad4f1323c39d Mon Sep 17 00:00:00 2001 +From: The8472 <git@infinite-source.de> +Date: Fri, 2 Apr 2021 23:06:05 +0200 +Subject: [PATCH 3/3] cleanup leak after test to make miri happy + +--- + library/alloc/tests/vec.rs | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs +index b926c697d58ab..b9fe07c73e55e 100644 +--- a/library/alloc/tests/vec.rs ++++ b/library/alloc/tests/vec.rs +@@ -1,3 +1,4 @@ ++use alloc::boxed::Box; + use std::borrow::Cow; + use std::cell::Cell; + use std::collections::TryReserveError::*; +@@ -1056,14 +1057,14 @@ fn test_from_iter_specialization_panic_during_drop_leaks() { + + #[derive(Debug)] + enum Droppable { +- DroppedTwice(Box<i32>), ++ DroppedTwice, + PanicOnDrop, + } + + impl Drop for Droppable { + fn drop(&mut self) { + match self { +- Droppable::DroppedTwice(_) => { ++ Droppable::DroppedTwice => { + unsafe { + DROP_COUNTER += 1; + } +@@ -1078,12 +1079,21 @@ fn test_from_iter_specialization_panic_during_drop_leaks() { + } + } + ++ let mut to_free: *mut Droppable = core::ptr::null_mut(); ++ let mut cap = 0; ++ + let _ = std::panic::catch_unwind(AssertUnwindSafe(|| { +- let v = vec![Droppable::DroppedTwice(Box::new(123)), Droppable::PanicOnDrop]; ++ let mut v = vec![Droppable::DroppedTwice, Droppable::PanicOnDrop]; ++ to_free = v.as_mut_ptr(); ++ cap = v.capacity(); + let _ = v.into_iter().take(0).collect::<Vec<_>>(); + })); + + assert_eq!(unsafe { DROP_COUNTER }, 1); ++ // clean up the leak to keep miri happy ++ unsafe { ++ Vec::from_raw_parts(to_free, 0, cap); ++ } + } + + #[test] |