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