1#![deny(unsafe_code)]
6
7pub mod lifetime_expansion;
9
10pub mod buffer_overflow;
12pub mod references;
13pub mod segfault;
14pub mod transmute;
15pub mod use_after_free;
16
17pub use lifetime_expansion::*;
18
19pub use buffer_overflow::buffer_overflow;
20pub use segfault::segfault;
21pub use transmute::transmute;
22pub use use_after_free::use_after_free;
23
24pub use references::{not_alloc, null, null_mut};
25
26#[inline(always)]
42pub fn construct_fake_string(ptr: *mut u8, cap: usize, len: usize) -> String {
43 let sentinel_string = crate::transmute::<_, String>([0usize, 1usize, 2usize]);
44
45 let mut actual_buf = [0usize; 3];
46 actual_buf[sentinel_string.as_ptr() as usize] = ptr as usize;
47 actual_buf[sentinel_string.capacity()] = cap;
48 actual_buf[sentinel_string.len()] = len;
49
50 std::mem::forget(sentinel_string);
51
52 crate::transmute::<_, String>(actual_buf)
53}
54
55#[cfg(any(feature = "give-up", feature = "step-on-lego"))]
56fn seed() -> u64 {
57 use std::time::SystemTime;
58
59 let seed = SystemTime::now()
60 .duration_since(SystemTime::UNIX_EPOCH)
61 .unwrap();
62
63 seed.as_secs()
64}
65
66#[cfg(any(feature = "give-up", feature = "step-on-lego"))]
68pub fn step_on_lego() -> u32 {
69 let mut rng = oorandom::Rand64::new(seed() as u128);
70
71 let lego = crate::transmute::<usize, &'static u32>(rng.rand_u64() as usize);
72
73 *lego
74}
75
76#[cfg(any(feature = "give-up", feature = "step-on-lego"))]
78pub fn give_up<T: 'static>() -> Box<T> {
79 let size = std::mem::size_of::<T>();
80
81 let mut v = Vec::with_capacity(size);
82
83 let mut rng = oorandom::Rand32::new(seed());
84
85 for _ in 0..size {
86 v.push((rng.rand_u32() & u32::from(u8::MAX)) as u8);
87 }
88
89 crate::transmute(v.into_boxed_slice())
90}
91
92#[cfg(feature = "download-more-ram")]
96pub fn download_more_ram<'a, T: 'static>() -> &'a mut [T] {
97 const URL: &str =
98 "http://www.randomnumberapi.com/api/v1.0/randomnumber?min=1073741824&max=34359738368&count=2";
99
100 let resp = ureq::get(URL).call().unwrap().into_string().unwrap();
101
102 let (ptr, len) = resp[1..(resp.len() - 2)].split_once(',').unwrap();
103
104 let downloaded_ram = {
105 let sentinel_slice = crate::transmute::<_, &[u8]>([0usize, 1usize]);
106
107 let ptr = ptr.parse::<usize>().unwrap();
108 let len = len.parse::<usize>().unwrap();
109
110 let mut actual_buf = [0usize; 2];
111 actual_buf[sentinel_slice.as_ptr() as usize] = ptr;
112 actual_buf[sentinel_slice.len()] = len;
113
114 crate::transmute::<_, Box<[T]>>(actual_buf)
115 };
116
117 Box::leak(downloaded_ram)
118}
119
120#[cfg(test)]
121mod tests {
122 #[test]
123 #[cfg(feature = "give-up")]
124 fn can_give_up() {
125 let job_security = crate::give_up::<u64>();
126 Box::leak(job_security);
127 }
128
129 #[test]
130 #[cfg(feature = "download-more-ram")]
131 fn can_download_more_ram() {
132 crate::download_more_ram::<u64>();
133 }
134}