• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #![cfg(feature = "derive")]
2 // Various structs/fields that we are deriving `Arbitrary` for aren't actually
3 // used except to exercise the derive.
4 #![allow(dead_code)]
5 // Various assert_eq! are used to compare result of bool amongst other data types
6 // In this case, using assert! is less explicit and readable
7 #![allow(clippy::bool_assert_comparison)]
8 
9 use arbitrary::*;
10 
arbitrary_from<'a, T: Arbitrary<'a>>(input: &'a [u8]) -> T11 fn arbitrary_from<'a, T: Arbitrary<'a>>(input: &'a [u8]) -> T {
12     let mut buf = Unstructured::new(input);
13     T::arbitrary(&mut buf).expect("can create arbitrary instance OK")
14 }
15 
16 #[derive(Copy, Clone, Debug, Eq, PartialEq, Arbitrary)]
17 pub struct Rgb {
18     pub r: u8,
19     pub g: u8,
20     pub b: u8,
21 }
22 
23 #[test]
struct_with_named_fields()24 fn struct_with_named_fields() {
25     let rgb: Rgb = arbitrary_from(&[4, 5, 6]);
26     assert_eq!(rgb.r, 4);
27     assert_eq!(rgb.g, 5);
28     assert_eq!(rgb.b, 6);
29 
30     assert_eq!((3, Some(3)), <Rgb as Arbitrary>::size_hint(0));
31 }
32 
33 #[derive(Copy, Clone, Debug, Arbitrary)]
34 struct MyTupleStruct(u8, bool);
35 
36 #[test]
tuple_struct()37 fn tuple_struct() {
38     let s: MyTupleStruct = arbitrary_from(&[43, 42]);
39     assert_eq!(s.0, 43);
40     assert_eq!(s.1, false);
41 
42     let s: MyTupleStruct = arbitrary_from(&[42, 43]);
43     assert_eq!(s.0, 42);
44     assert_eq!(s.1, true);
45 
46     assert_eq!((2, Some(2)), <MyTupleStruct as Arbitrary>::size_hint(0));
47 }
48 
49 #[derive(Clone, Debug, Arbitrary)]
50 struct EndingInVec(u8, bool, u32, Vec<u16>);
51 #[derive(Clone, Debug, Arbitrary)]
52 struct EndingInString(u8, bool, u32, String);
53 
54 #[test]
test_take_rest()55 fn test_take_rest() {
56     let bytes = [1, 1, 1, 2, 3, 4, 5, 6, 7, 8];
57     let s1 = EndingInVec::arbitrary_take_rest(Unstructured::new(&bytes)).unwrap();
58     let s2 = EndingInString::arbitrary_take_rest(Unstructured::new(&bytes)).unwrap();
59     assert_eq!(s1.0, 1);
60     assert_eq!(s2.0, 1);
61     assert_eq!(s1.1, true);
62     assert_eq!(s2.1, true);
63     assert_eq!(s1.2, 0x4030201);
64     assert_eq!(s2.2, 0x4030201);
65     assert_eq!(s1.3, vec![0x0706]);
66     assert_eq!(s2.3, "\x05\x06\x07\x08");
67 }
68 
69 #[derive(Copy, Clone, Debug, Arbitrary)]
70 enum MyEnum {
71     Unit,
72     Tuple(u8, u16),
73     Struct { a: u32, b: (bool, u64) },
74 }
75 
76 #[test]
derive_enum()77 fn derive_enum() {
78     let mut raw = vec![
79         // The choice of which enum variant takes 4 bytes.
80         1, 2, 3, 4,
81         // And then we need up to 13 bytes for creating `MyEnum::Struct`, the
82         // largest variant.
83         1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
84     ];
85 
86     let mut saw_unit = false;
87     let mut saw_tuple = false;
88     let mut saw_struct = false;
89 
90     for i in 0..=255 {
91         // Choose different variants each iteration.
92         for el in &mut raw[..4] {
93             *el = i;
94         }
95 
96         let e: MyEnum = arbitrary_from(&raw);
97 
98         match e {
99             MyEnum::Unit => {
100                 saw_unit = true;
101             }
102             MyEnum::Tuple(a, b) => {
103                 saw_tuple = true;
104                 assert_eq!(a, arbitrary_from(&raw[4..5]));
105                 assert_eq!(b, arbitrary_from(&raw[5..]));
106             }
107             MyEnum::Struct { a, b } => {
108                 saw_struct = true;
109                 assert_eq!(a, arbitrary_from(&raw[4..8]));
110                 assert_eq!(b, arbitrary_from(&raw[8..]));
111             }
112         }
113     }
114 
115     assert!(saw_unit);
116     assert!(saw_tuple);
117     assert!(saw_struct);
118 
119     assert_eq!((4, Some(17)), <MyEnum as Arbitrary>::size_hint(0));
120 }
121 
122 // This should result in a compiler-error:
123 // #[derive(Arbitrary, Debug)]
124 // enum Never {
125 //     #[arbitrary(skip)]
126 //     Nope,
127 // }
128 
129 #[derive(Arbitrary, Debug)]
130 enum SkipVariant {
131     Always,
132     #[arbitrary(skip)]
133     Never,
134 }
135 
136 #[test]
test_skip_variant()137 fn test_skip_variant() {
138     (0..=u8::MAX).for_each(|byte| {
139         let buffer = [byte];
140         let unstructured = Unstructured::new(&buffer);
141         let skip_variant = SkipVariant::arbitrary_take_rest(unstructured).unwrap();
142         assert!(!matches!(skip_variant, SkipVariant::Never));
143     })
144 }
145 
146 #[derive(Arbitrary, Debug)]
147 enum RecursiveTree {
148     Leaf,
149     Node {
150         left: Box<RecursiveTree>,
151         right: Box<RecursiveTree>,
152     },
153 }
154 
155 #[derive(Arbitrary, Debug)]
156 struct WideRecursiveStruct {
157     a: Option<Box<WideRecursiveStruct>>,
158     b: Option<Box<WideRecursiveStruct>>,
159     c: Option<Box<WideRecursiveStruct>>,
160     d: Option<Box<WideRecursiveStruct>>,
161     e: Option<Box<WideRecursiveStruct>>,
162     f: Option<Box<WideRecursiveStruct>>,
163     g: Option<Box<WideRecursiveStruct>>,
164     h: Option<Box<WideRecursiveStruct>>,
165     i: Option<Box<WideRecursiveStruct>>,
166     k: Option<Box<WideRecursiveStruct>>,
167 }
168 
169 #[derive(Arbitrary, Debug)]
170 enum WideRecursiveEnum {
171     None,
172     A(Box<WideRecursiveStruct>),
173     B(Box<WideRecursiveStruct>),
174     C(Box<WideRecursiveStruct>),
175     D(Box<WideRecursiveStruct>),
176     E(Box<WideRecursiveStruct>),
177     F(Box<WideRecursiveStruct>),
178     G(Box<WideRecursiveStruct>),
179     H(Box<WideRecursiveStruct>),
180     I(Box<WideRecursiveStruct>),
181     K(Box<WideRecursiveStruct>),
182 }
183 
184 #[derive(Arbitrary, Debug)]
185 enum WideRecursiveMixedEnum {
186     None,
187     A(Box<WideRecursiveMixedEnum>),
188     B(Box<WideRecursiveMixedEnum>),
189     C(Box<WideRecursiveMixedEnum>),
190     D(Box<WideRecursiveMixedEnum>),
191     E(Box<WideRecursiveMixedEnum>),
192     F(Box<WideRecursiveMixedStruct>),
193     G(Box<WideRecursiveMixedStruct>),
194     H(Box<WideRecursiveMixedStruct>),
195     I(Box<WideRecursiveMixedStruct>),
196     K(Box<WideRecursiveMixedStruct>),
197 }
198 
199 #[derive(Arbitrary, Debug)]
200 struct WideRecursiveMixedStruct {
201     a: Option<Box<WideRecursiveMixedEnum>>,
202     b: Option<Box<WideRecursiveMixedEnum>>,
203     c: Option<Box<WideRecursiveMixedEnum>>,
204     d: Option<Box<WideRecursiveMixedEnum>>,
205     e: Option<Box<WideRecursiveMixedEnum>>,
206     f: Option<Box<WideRecursiveMixedStruct>>,
207     g: Option<Box<WideRecursiveMixedStruct>>,
208     h: Option<Box<WideRecursiveMixedStruct>>,
209     i: Option<Box<WideRecursiveMixedStruct>>,
210     k: Option<Box<WideRecursiveMixedStruct>>,
211 }
212 
213 #[test]
recursive()214 fn recursive() {
215     let raw = vec![1, 2, 3, 4, 5, 6, 7, 8, 9];
216     let _rec: RecursiveTree = arbitrary_from(&raw);
217     let _rec: WideRecursiveStruct = arbitrary_from(&raw);
218     let _rec: WideRecursiveEnum = arbitrary_from(&raw);
219     let _rec: WideRecursiveMixedStruct = arbitrary_from(&raw);
220     let _rec: WideRecursiveMixedEnum = arbitrary_from(&raw);
221 
222     assert_eq!((0, None), <WideRecursiveStruct as Arbitrary>::size_hint(0));
223     assert_eq!((0, None), <WideRecursiveEnum as Arbitrary>::size_hint(0));
224     assert_eq!(
225         (0, None),
226         <WideRecursiveMixedStruct as Arbitrary>::size_hint(0)
227     );
228     assert_eq!(
229         (0, None),
230         <WideRecursiveMixedEnum as Arbitrary>::size_hint(0)
231     );
232 
233     let (lower, upper) = <RecursiveTree as Arbitrary>::size_hint(0);
234     assert_eq!(lower, 0, "Cannot compute size hint of recursive structure");
235     assert!(
236         upper.is_none(),
237         "potentially infinitely recursive, so no upper bound"
238     );
239 }
240 
241 #[derive(Arbitrary, Debug)]
242 struct Generic<T> {
243     inner: T,
244 }
245 
246 #[test]
generics()247 fn generics() {
248     let raw = vec![1, 2, 3, 4, 5, 6, 7, 8, 9];
249     let gen: Generic<bool> = arbitrary_from(&raw);
250     assert!(gen.inner);
251 
252     let (lower, upper) = <Generic<u32> as Arbitrary>::size_hint(0);
253     assert_eq!(lower, 4);
254     assert_eq!(upper, Some(4));
255 }
256 
257 #[derive(Arbitrary, Debug)]
258 struct OneLifetime<'a> {
259     alpha: &'a str,
260 }
261 
262 #[test]
one_lifetime()263 fn one_lifetime() {
264     // Last byte is used for length
265     let raw: Vec<u8> = vec![97, 98, 99, 100, 3];
266     let lifetime: OneLifetime = arbitrary_from(&raw);
267     assert_eq!("abc", lifetime.alpha);
268 
269     let (lower, upper) = <OneLifetime as Arbitrary>::size_hint(0);
270     assert_eq!(lower, 0);
271     assert_eq!(upper, None);
272 }
273 
274 #[derive(Arbitrary, Debug)]
275 struct TwoLifetimes<'a, 'b> {
276     alpha: &'a str,
277     beta: &'b str,
278 }
279 
280 #[test]
two_lifetimes()281 fn two_lifetimes() {
282     // Last byte is used for length
283     let raw: Vec<u8> = vec![97, 98, 99, 100, 101, 102, 103, 3];
284     let lifetime: TwoLifetimes = arbitrary_from(&raw);
285     assert_eq!("abc", lifetime.alpha);
286     assert_eq!("def", lifetime.beta);
287 
288     let (lower, upper) = <TwoLifetimes as Arbitrary>::size_hint(0);
289     assert_eq!(lower, 0);
290     assert_eq!(upper, None);
291 }
292 
293 #[test]
recursive_and_empty_input()294 fn recursive_and_empty_input() {
295     // None of the following derives should result in a stack overflow. See
296     // https://github.com/rust-fuzz/arbitrary/issues/107 for details.
297 
298     #[derive(Debug, Arbitrary)]
299     enum Nat {
300         Succ(Box<Nat>),
301         Zero,
302     }
303 
304     let _ = Nat::arbitrary(&mut Unstructured::new(&[]));
305 
306     #[derive(Debug, Arbitrary)]
307     enum Nat2 {
308         Zero,
309         Succ(Box<Nat2>),
310     }
311 
312     let _ = Nat2::arbitrary(&mut Unstructured::new(&[]));
313 
314     #[derive(Debug, Arbitrary)]
315     struct Nat3 {
316         f: Option<Box<Nat3>>,
317     }
318 
319     let _ = Nat3::arbitrary(&mut Unstructured::new(&[]));
320 
321     #[derive(Debug, Arbitrary)]
322     struct Nat4(Option<Box<Nat4>>);
323 
324     let _ = Nat4::arbitrary(&mut Unstructured::new(&[]));
325 
326     #[derive(Debug, Arbitrary)]
327     enum Nat5 {
328         Zero,
329         Succ { f: Box<Nat5> },
330     }
331 
332     let _ = Nat5::arbitrary(&mut Unstructured::new(&[]));
333 }
334 
335 #[test]
test_field_attributes()336 fn test_field_attributes() {
337     // A type that DOES NOT implement Arbitrary
338     #[derive(Debug)]
339     struct Weight(u8);
340 
341     #[derive(Debug, Arbitrary)]
342     struct Parcel {
343         #[arbitrary(with = arbitrary_weight)]
344         weight: Weight,
345 
346         #[arbitrary(default)]
347         width: u8,
348 
349         #[arbitrary(value = 2 + 2)]
350         length: u8,
351 
352         height: u8,
353 
354         #[arbitrary(with = |u: &mut Unstructured| u.int_in_range(0..=100))]
355         price: u8,
356     }
357 
358     fn arbitrary_weight(u: &mut Unstructured) -> arbitrary::Result<Weight> {
359         u.int_in_range(45..=56).map(Weight)
360     }
361 
362     let parcel: Parcel = arbitrary_from(&[6, 199, 17]);
363 
364     // 45 + 6 = 51
365     assert_eq!(parcel.weight.0, 51);
366 
367     // u8::default()
368     assert_eq!(parcel.width, 0);
369 
370     // 2 + 2 = 4
371     assert_eq!(parcel.length, 4);
372 
373     // 199 is the 2nd byte used by arbitrary
374     assert_eq!(parcel.height, 199);
375 
376     // 17 is the 3rd byte used by arbitrary
377     assert_eq!(parcel.price, 17);
378 }
379 
380 #[test]
derive_structs_named_same_as_core()381 fn derive_structs_named_same_as_core() {
382     #[derive(Debug, Arbitrary)]
383     struct Option {
384         f: core::option::Option<u32>,
385     }
386 
387     let _ = Option::arbitrary(&mut Unstructured::new(&[]));
388 
389     #[derive(Debug, Default, Arbitrary)]
390     struct Default {
391         f: u32,
392     }
393 
394     let _ = Default::arbitrary(&mut Unstructured::new(&[]));
395 }
396