]> git.lizzy.rs Git - rust.git/commitdiff
Add test of leaking a binary_heap PeekMut
authorDavid Tolnay <dtolnay@gmail.com>
Sun, 18 Dec 2022 17:40:23 +0000 (09:40 -0800)
committerDavid Tolnay <dtolnay@gmail.com>
Sat, 14 Jan 2023 21:28:14 +0000 (13:28 -0800)
library/alloc/src/collections/binary_heap/tests.rs
library/alloc/src/lib.rs

index 59c516374c0e2790d6c2357b6ed1566afa7c2344..ffbb6c80ac01847999294b6dee8af0b81fa0dc4f 100644 (file)
@@ -1,6 +1,7 @@
 use super::*;
 use crate::boxed::Box;
 use crate::testing::crash_test::{CrashTestDummy, Panic};
+use core::mem;
 use std::iter::TrustedLen;
 use std::panic::{catch_unwind, AssertUnwindSafe};
 
@@ -146,6 +147,24 @@ fn test_peek_mut() {
     assert_eq!(heap.peek(), Some(&9));
 }
 
+#[test]
+fn test_peek_mut_leek() {
+    let data = vec![4, 2, 7];
+    let mut heap = BinaryHeap::from(data);
+    let mut max = heap.peek_mut().unwrap();
+    *max = -1;
+
+    // The PeekMut object's Drop impl would have been responsible for moving the
+    // -1 out of the max position of the BinaryHeap, but we don't run it.
+    mem::forget(max);
+
+    // Absent some mitigation like leak amplification, the -1 would incorrectly
+    // end up in the last position of the returned Vec, with the rest of the
+    // heap's original contents in front of it in sorted order.
+    let sorted_vec = heap.into_sorted_vec();
+    assert!(sorted_vec.is_sorted(), "{:?}", sorted_vec);
+}
+
 #[test]
 fn test_peek_mut_pop() {
     let data = vec![2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1];
index 4e812529c2cc846d7934672a05202a0eb9db7218..afc3a3dc6a8c6bb646b725f281052558f61e7844 100644 (file)
 #![feature(hasher_prefixfree_extras)]
 #![feature(inline_const)]
 #![feature(inplace_iteration)]
+#![cfg_attr(test, feature(is_sorted))]
 #![feature(iter_advance_by)]
 #![feature(iter_next_chunk)]
 #![feature(iter_repeat_n)]