• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use {
2     crate::{Arbitrary, Error, MaxRecursionReached, Result, Unstructured},
3     core::{
4         mem,
5         num::{
6             NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize, NonZeroU128,
7             NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize, Wrapping,
8         },
9     },
10 };
11 
12 macro_rules! impl_arbitrary_for_integers {
13     ( $( $ty:ty; )* ) => {
14         $(
15             impl<'a> Arbitrary<'a> for $ty {
16                 fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
17                     let mut buf = [0; mem::size_of::<$ty>()];
18                     u.fill_buffer(&mut buf)?;
19                     Ok(Self::from_le_bytes(buf))
20                 }
21 
22                 #[inline]
23                 fn size_hint(_depth: usize) -> (usize, Option<usize>) {
24                     let n = mem::size_of::<$ty>();
25                     (n, Some(n))
26                 }
27 
28             }
29         )*
30     }
31 }
32 
33 impl_arbitrary_for_integers! {
34     u8;
35     u16;
36     u32;
37     u64;
38     u128;
39     i8;
40     i16;
41     i32;
42     i64;
43     i128;
44 }
45 
46 // Note: We forward Arbitrary for i/usize to i/u64 in order to simplify corpus
47 // compatibility between 32-bit and 64-bit builds. This introduces dead space in
48 // 32-bit builds but keeps the input layout independent of the build platform.
49 impl<'a> Arbitrary<'a> for usize {
arbitrary(u: &mut Unstructured<'a>) -> Result<Self>50     fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
51         u.arbitrary::<u64>().map(|x| x as usize)
52     }
53 
54     #[inline]
size_hint(depth: usize) -> (usize, Option<usize>)55     fn size_hint(depth: usize) -> (usize, Option<usize>) {
56         <u64 as Arbitrary>::size_hint(depth)
57     }
58 }
59 
60 impl<'a> Arbitrary<'a> for isize {
arbitrary(u: &mut Unstructured<'a>) -> Result<Self>61     fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
62         u.arbitrary::<i64>().map(|x| x as isize)
63     }
64 
65     #[inline]
size_hint(depth: usize) -> (usize, Option<usize>)66     fn size_hint(depth: usize) -> (usize, Option<usize>) {
67         <i64 as Arbitrary>::size_hint(depth)
68     }
69 }
70 
71 macro_rules! impl_arbitrary_for_floats {
72     ( $( $ty:ident : $unsigned:ty; )* ) => {
73         $(
74             impl<'a> Arbitrary<'a> for $ty {
75                 fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
76                     Ok(Self::from_bits(<$unsigned as Arbitrary<'a>>::arbitrary(u)?))
77                 }
78 
79                 #[inline]
80                 fn size_hint(depth: usize) -> (usize, Option<usize>) {
81                     <$unsigned as Arbitrary<'a>>::size_hint(depth)
82                 }
83             }
84         )*
85     }
86 }
87 
88 impl_arbitrary_for_floats! {
89     f32: u32;
90     f64: u64;
91 }
92 
93 macro_rules! implement_nonzero_int {
94     ($nonzero:ty, $int:ty) => {
95         impl<'a> Arbitrary<'a> for $nonzero {
96             fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
97                 match Self::new(<$int as Arbitrary<'a>>::arbitrary(u)?) {
98                     Some(n) => Ok(n),
99                     None => Err(Error::IncorrectFormat),
100                 }
101             }
102 
103             #[inline]
104             fn size_hint(depth: usize) -> (usize, Option<usize>) {
105                 <$int as Arbitrary<'a>>::size_hint(depth)
106             }
107         }
108     };
109 }
110 
111 implement_nonzero_int! { NonZeroI8, i8 }
112 implement_nonzero_int! { NonZeroI16, i16 }
113 implement_nonzero_int! { NonZeroI32, i32 }
114 implement_nonzero_int! { NonZeroI64, i64 }
115 implement_nonzero_int! { NonZeroI128, i128 }
116 implement_nonzero_int! { NonZeroIsize, isize }
117 implement_nonzero_int! { NonZeroU8, u8 }
118 implement_nonzero_int! { NonZeroU16, u16 }
119 implement_nonzero_int! { NonZeroU32, u32 }
120 implement_nonzero_int! { NonZeroU64, u64 }
121 implement_nonzero_int! { NonZeroU128, u128 }
122 implement_nonzero_int! { NonZeroUsize, usize }
123 
124 impl<'a, A> Arbitrary<'a> for Wrapping<A>
125 where
126     A: Arbitrary<'a>,
127 {
arbitrary(u: &mut Unstructured<'a>) -> Result<Self>128     fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
129         Arbitrary::arbitrary(u).map(Wrapping)
130     }
131 
132     #[inline]
size_hint(depth: usize) -> (usize, Option<usize>)133     fn size_hint(depth: usize) -> (usize, Option<usize>) {
134         Self::try_size_hint(depth).unwrap_or_default()
135     }
136 
137     #[inline]
try_size_hint(depth: usize) -> Result<(usize, Option<usize>), MaxRecursionReached>138     fn try_size_hint(depth: usize) -> Result<(usize, Option<usize>), MaxRecursionReached> {
139         <A as Arbitrary<'a>>::try_size_hint(depth)
140     }
141 }
142