1#![forbid(unsafe_code)] #![cfg_attr(doc, feature(doc_auto_cfg))]
3#[inline(always)]
24#[cfg(any(feature = "test-borrow", doc))]
25pub fn extend<'a, T>(input: &'a T) -> &'static T {
26 struct Bounded<'a, 'b: 'static, T>(&'a T, [&'b (); 0]);
27 let n: Box<dyn FnOnce(&T) -> Bounded<'static, '_, T>> = Box::new(|x| Bounded(x, []));
28 n(input).0
29}
30#[inline(always)]
32#[cfg(any(feature = "test-borrow-mut", doc))]
33pub fn extend_mut<'a, T>(input: &'a mut T) -> &'static mut T {
34 struct Bounded<'a, 'b: 'static, T>(&'a mut T, [&'b (); 0]);
35 let mut n: Box<dyn FnMut(&mut T) -> Bounded<'static, '_, T>> = Box::new(|x| Bounded(x, []));
36 n(input).0
37}
38#[inline(always)]
40#[cfg(any(feature = "test-fake-static-borrow", doc))]
41pub fn make_static<'a, T>(input: &'a T) -> &'static T {
42 fn helper<'a, T>(_: [&'static &'a (); 0], v: &'a T) -> &'static T {
43 v
44 }
45 let f: fn([&'static &(); 0], &T) -> &'static T = helper;
46 f([], input) }
48#[inline(always)]
50#[cfg(any(feature = "test-fake-static-borrow-mut", doc))]
51pub fn make_static_mut<'a, T>(input: &'a mut T) -> &'static mut T {
52 fn helper_mut<'a, T>(_: [&'static &'a (); 0], v: &'a mut T) -> &'static mut T {
53 v
54 }
55 let f: fn([&'static &'static (); 0], &'a mut T) -> &'static mut T = helper_mut;
56 f([], input)
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63 #[test]
64 #[should_panic]
65 #[cfg(feature = "test-borrow-mut")]
66 fn it_panics() {
67 let mut a = vec![1, 2, 3, 4, 5, 6, 7, 8];
68 let b = extend_mut(&mut a);
69 drop(a);
70 panic!("{b:?} is still readable!");
72 }
73 #[test]
74 #[should_panic]
75 #[cfg(feature = "test-borrow")]
76 fn uaf() {
77 let a = vec![1, 2, 3, 4];
78 let b = extend(&a);
79 drop(a);
80 assert_eq!(b, &[1, 2, 3, 4]);
81 }
82 #[test]
83 #[should_panic]
84 #[cfg(feature = "test-fake-static-borrow-mut")]
85 fn it_panics_2() {
86 let mut a = vec![1, 2, 3, 4, 5, 6, 7, 8];
87 let b = make_static_mut(&mut a);
88 drop(a);
89 panic!("{b:?} is still readable!");
91 }
92 #[test]
93 #[should_panic]
94 #[cfg(feature = "test-fake-static-borrow")]
95 fn uaf_2() {
96 let a = vec![1, 2, 3, 4];
97 let b = make_static(&a);
98 drop(a);
99 assert_eq!(b, &[1, 2, 3, 4]);
100 }
101}