]> git.proxmox.com Git - rustc.git/blame - vendor/zeroize/tests/zeroize_derive.rs
New upstream version 1.76.0+dfsg1
[rustc.git] / vendor / zeroize / tests / zeroize_derive.rs
CommitLineData
0a29b90c
FG
1//! Integration tests for `zeroize_derive` proc macros
2#![cfg(feature = "zeroize_derive")]
3
4use zeroize::{Zeroize, ZeroizeOnDrop};
5
6#[test]
7fn derive_tuple_struct_test() {
8 #[derive(Zeroize, ZeroizeOnDrop)]
9 struct Z([u8; 3]);
10
11 let mut value = Z([1, 2, 3]);
12 value.zeroize();
13 assert_eq!(&value.0, &[0, 0, 0])
14}
15
16#[test]
17#[cfg(feature = "alloc")]
18fn derive_struct_test() {
19 #[derive(Zeroize, ZeroizeOnDrop)]
20 struct Z {
21 string: String,
22 vec: Vec<u8>,
23 bytearray: [u8; 3],
24 number: usize,
25 boolean: bool,
26 }
27
28 let mut value = Z {
29 string: String::from("Hello, world!"),
30 vec: vec![1, 2, 3],
31 bytearray: [4, 5, 6],
32 number: 42,
33 boolean: true,
34 };
35
36 value.zeroize();
37
38 assert!(value.string.is_empty());
39 assert!(value.vec.is_empty());
40 assert_eq!(&value.bytearray, &[0, 0, 0]);
41 assert_eq!(value.number, 0);
42 assert!(!value.boolean);
43}
44
45#[test]
46fn derive_enum_test() {
47 #[derive(Zeroize, ZeroizeOnDrop)]
48 enum Z {
49 #[allow(dead_code)]
50 Variant1,
51 Variant2(usize),
52 }
53
54 let mut value = Z::Variant2(26);
55
56 value.zeroize();
57
58 assert!(matches!(value, Z::Variant2(0)));
59}
60
61/// Test that the custom macro actually derived `Drop` for `Z`
62#[test]
63fn derive_struct_drop() {
64 #[derive(Zeroize, ZeroizeOnDrop)]
65 struct Z([u8; 3]);
66
67 assert!(std::mem::needs_drop::<Z>());
68}
69
70/// Test that the custom macro actually derived `Drop` for `Z`
71#[test]
72fn derive_enum_drop() {
73 #[allow(dead_code)]
74 #[derive(Zeroize, ZeroizeOnDrop)]
75 enum Z {
76 Variant1,
77 Variant2(usize),
78 }
79
80 assert!(std::mem::needs_drop::<Z>());
81}
82
83/// Test that the custom macro actually derived `Drop` for `Z`
84#[test]
85fn derive_struct_only_drop() {
86 #[derive(ZeroizeOnDrop)]
87 struct Z([u8; 3]);
88
89 assert!(std::mem::needs_drop::<Z>());
90}
91
92/// Test that the custom macro actually derived `Drop` for `Z`
93#[test]
94fn derive_enum_only_drop() {
95 #[allow(dead_code)]
96 #[derive(ZeroizeOnDrop)]
97 enum Z {
98 Variant1,
99 Variant2(usize),
100 }
101
102 assert!(std::mem::needs_drop::<Z>());
103}
104
105/// Test that `Drop` is not derived in the following case by defining a
106/// `Drop` impl which should conflict if the custom derive defined one too
107#[allow(dead_code)]
108#[derive(Zeroize)]
109struct ZeroizeNoDropStruct([u8; 3]);
110
111impl Drop for ZeroizeNoDropStruct {
112 fn drop(&mut self) {}
113}
114
115#[allow(dead_code)]
116#[derive(Zeroize)]
117enum ZeroizeNoDropEnum {
118 Variant([u8; 3]),
119}
120
121impl Drop for ZeroizeNoDropEnum {
122 fn drop(&mut self) {}
123}
124
125#[test]
126#[cfg(feature = "alloc")]
127fn derive_struct_skip() {
128 #[derive(Zeroize, ZeroizeOnDrop)]
129 struct Z {
130 string: String,
131 vec: Vec<u8>,
132 #[zeroize(skip)]
133 bytearray: [u8; 3],
134 number: usize,
135 boolean: bool,
136 }
137
138 let mut value = Z {
139 string: String::from("Hello, world!"),
140 vec: vec![1, 2, 3],
141 bytearray: [4, 5, 6],
142 number: 42,
143 boolean: true,
144 };
145
146 value.zeroize();
147
148 assert!(value.string.is_empty());
149 assert!(value.vec.is_empty());
150 assert_eq!(&value.bytearray, &[4, 5, 6]);
151 assert_eq!(value.number, 0);
152 assert!(!value.boolean);
153}
154
155#[test]
156#[cfg(feature = "alloc")]
157fn derive_enum_skip() {
158 #[derive(Zeroize, ZeroizeOnDrop)]
159 enum Z {
160 #[allow(dead_code)]
161 Variant1,
162 #[zeroize(skip)]
163 Variant2([u8; 3]),
164 #[zeroize(skip)]
165 Variant3 {
166 string: String,
167 vec: Vec<u8>,
168 bytearray: [u8; 3],
169 number: usize,
170 boolean: bool,
171 },
172 Variant4 {
173 string: String,
174 vec: Vec<u8>,
175 #[zeroize(skip)]
176 bytearray: [u8; 3],
177 number: usize,
178 boolean: bool,
179 },
180 }
181
182 let mut value = Z::Variant2([4, 5, 6]);
183
184 value.zeroize();
185
186 assert!(matches!(&value, Z::Variant2([4, 5, 6])));
187
188 let mut value = Z::Variant3 {
189 string: String::from("Hello, world!"),
190 vec: vec![1, 2, 3],
191 bytearray: [4, 5, 6],
192 number: 42,
193 boolean: true,
194 };
195
196 value.zeroize();
197
198 assert!(matches!(
199 &value,
200 Z::Variant3 { string, vec, bytearray, number, boolean }
201 if string == "Hello, world!" &&
202 vec == &[1, 2, 3] &&
203 bytearray == &[4, 5, 6] &&
204 *number == 42 &&
205 *boolean
206 ));
207
208 let mut value = Z::Variant4 {
209 string: String::from("Hello, world!"),
210 vec: vec![1, 2, 3],
211 bytearray: [4, 5, 6],
212 number: 42,
213 boolean: true,
214 };
215
216 value.zeroize();
217
218 assert!(matches!(
219 &value,
220 Z::Variant4 { string, vec, bytearray, number, boolean }
221 if string.is_empty() &&
222 vec.is_empty() &&
223 bytearray == &[4, 5, 6] &&
224 *number == 0 &&
225 !boolean
226 ));
227}
228
229#[test]
230fn derive_bound() {
231 trait T: Zeroize {}
232
233 impl T for u8 {}
234
235 #[derive(Zeroize)]
236 #[zeroize(bound = "X: T")]
237 struct Z<X>(X);
238
239 let mut value = Z(5_u8);
240
241 value.zeroize();
242
243 assert_eq!(value.0, 0);
244}
245
246#[test]
247fn derive_inherit_zeroize_on_drop() {
248 #[derive(ZeroizeOnDrop)]
249 struct X([u8; 3]);
250
251 #[derive(ZeroizeOnDrop)]
252 struct Z(X);
253
254 let mut value = Z(X([1, 2, 3]));
255 unsafe {
256 std::ptr::drop_in_place(&mut value);
257 }
258 assert_eq!(&value.0 .0, &[0, 0, 0])
259}
260
261#[test]
262fn derive_inherit_from_both() {
263 #[derive(Zeroize, ZeroizeOnDrop)]
264 struct X([u8; 3]);
265
266 #[derive(ZeroizeOnDrop)]
267 struct Z(X);
268
269 let mut value = Z(X([1, 2, 3]));
270 unsafe {
271 std::ptr::drop_in_place(&mut value);
272 }
273 assert_eq!(&value.0 .0, &[0, 0, 0])
274}
275
276#[test]
277fn derive_inherit_both() {
278 #[derive(Zeroize, ZeroizeOnDrop)]
279 struct X([u8; 3]);
280
281 #[derive(Zeroize, ZeroizeOnDrop)]
282 struct Z(X);
283
284 let mut value = Z(X([1, 2, 3]));
285 unsafe {
286 std::ptr::drop_in_place(&mut value);
287 }
288 assert_eq!(&value.0 .0, &[0, 0, 0])
289}
290
291#[test]
292fn derive_deref() {
293 struct X([u8; 3]);
294
295 impl std::ops::Deref for X {
296 type Target = [u8];
297
298 fn deref(&self) -> &Self::Target {
299 &self.0
300 }
301 }
302
303 impl std::ops::DerefMut for X {
304 fn deref_mut(&mut self) -> &mut Self::Target {
305 &mut self.0
306 }
307 }
308
309 #[derive(Zeroize, ZeroizeOnDrop)]
310 struct Z(X);
311
312 let mut value = Z(X([1, 2, 3]));
313 unsafe {
314 std::ptr::drop_in_place(&mut value);
315 }
316 assert_eq!(&value.0 .0, &[0, 0, 0])
317}
49aad941
FG
318
319#[test]
320#[cfg(feature = "alloc")]
321fn derive_zeroize_on_drop_generic() {
322 #[derive(ZeroizeOnDrop)]
323 struct Y<T: Zeroize>(Box<T>);
324
325 #[derive(ZeroizeOnDrop)]
326 struct Z<T: Zeroize>(Vec<T>);
327}
4b012472
FG
328
329#[test]
330fn derive_zeroize_unused_param() {
331 #[derive(Zeroize)]
332 struct Z<T> {
333 arr: [u32; 5],
334 #[zeroize(skip)]
335 skipped: T,
336 }
337}
338
339#[test]
340// Issue #878
341fn derive_zeroize_with_marker() {
342 #[derive(ZeroizeOnDrop, Zeroize)]
343 struct Test<A: Marker> {
344 #[zeroize(skip)]
345 field: Option<A>,
346 }
347
348 trait Secret: ZeroizeOnDrop + Zeroize {}
349
350 impl<A: Marker> Secret for Test<A> {}
351
352 trait Marker {}
353}
354
355#[test]
356// Issue #878
357fn derive_zeroize_used_param() {
358 #[derive(Zeroize)]
359 struct Z<T> {
360 used: T,
361 }
362}