diff options
| author | Jonas Schievink <jonasschievink@gmail.com> | 2019-12-13 18:36:35 +0100 |
|---|---|---|
| committer | Jonas Schievink <jonasschievink@gmail.com> | 2020-01-19 20:24:08 +0100 |
| commit | dc492452dae29d75b14afe3559f5fb59be7f2d3a (patch) | |
| tree | 3005b81d064c2a8bb8af93ac2cad49e126484292 /src/liballoc/collections | |
| parent | 5d04790dd2e73f3faf08d528e3675e131585ec01 (diff) | |
| download | rust-dc492452dae29d75b14afe3559f5fb59be7f2d3a.tar.gz rust-dc492452dae29d75b14afe3559f5fb59be7f2d3a.zip | |
Fix leak in btree_map::IntoIter when drop panics
Diffstat (limited to 'src/liballoc/collections')
| -rw-r--r-- | src/liballoc/collections/btree/map.rs | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs index 302c2bcd5e4..71ddfc4ef63 100644 --- a/src/liballoc/collections/btree/map.rs +++ b/src/liballoc/collections/btree/map.rs @@ -1381,7 +1381,22 @@ impl<K, V> IntoIterator for BTreeMap<K, V> { #[stable(feature = "btree_drop", since = "1.7.0")] impl<K, V> Drop for IntoIter<K, V> { fn drop(&mut self) { - self.for_each(drop); + struct DropGuard<'a, K, V>(&'a mut IntoIter<K, V>); + + impl<'a, K, V> Drop for DropGuard<'a, K, V> { + fn drop(&mut self) { + // Continue the same loop we perform below. This only runs when unwinding, so we + // don't have to care about panics this time (they'll abort). + while let Some(_) = self.0.next() {} + } + } + + while let Some(pair) = self.next() { + let guard = DropGuard(self); + drop(pair); + mem::forget(guard); + } + unsafe { let leaf_node = ptr::read(&self.front).into_node(); if leaf_node.is_shared_root() { |
