// Copyright © 2019 The Rust Fuzz Project Developers. // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. //! The `Arbitrary` trait crate. //! //! This trait provides an [`Arbitrary`](./trait.Arbitrary.html) trait to //! produce well-typed, structured values, from raw, byte buffers. It is //! generally intended to be used with fuzzers like AFL or libFuzzer. See the //! [`Arbitrary`](./trait.Arbitrary.html) trait's documentation for details on //! automatically deriving, implementing, and/or using the trait. #![deny(bad_style)] #![deny(missing_docs)] #![deny(future_incompatible)] #![deny(nonstandard_style)] #![deny(rust_2018_compatibility)] #![deny(rust_2018_idioms)] #![deny(unused)] #[cfg(feature = "derive_arbitrary")] pub use derive_arbitrary::*; mod error; pub use error::*; pub mod unstructured; #[doc(inline)] pub use unstructured::Unstructured; pub mod size_hint; use core::cell::{Cell, RefCell, UnsafeCell}; use core::iter; use core::mem; use core::ops::{Range, RangeBounds, RangeFrom, RangeInclusive, RangeTo, RangeToInclusive}; use core::str; use core::time::Duration; use std::borrow::{Cow, ToOwned}; use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque}; use std::ffi::{CString, OsString}; use std::path::PathBuf; use std::rc::Rc; use std::sync::atomic::{AtomicBool, AtomicIsize, AtomicUsize}; use std::sync::{Arc, Mutex}; /// Generate arbitrary structured values from raw, unstructured data. /// /// The `Arbitrary` trait allows you to generate valid structured values, like /// `HashMap`s, or ASTs, or `MyTomlConfig`, or any other data structure from /// raw, unstructured bytes provided by a fuzzer. /// /// # Deriving `Arbitrary` /// /// Automatically deriving the `Arbitrary` trait is the recommended way to /// implement `Arbitrary` for your types. /// /// Using the custom derive requires that you enable the `"derive"` cargo /// feature in your `Cargo.toml`: /// /// ```toml /// [dependencies] /// arbitrary = { version = "1", features = ["derive"] } /// ``` /// /// Then, you add the `#[derive(Arbitrary)]` annotation to your `struct` or /// `enum` type definition: /// /// ``` /// # #[cfg(feature = "derive")] mod foo { /// use arbitrary::Arbitrary; /// use std::collections::HashSet; /// /// #[derive(Arbitrary)] /// pub struct AddressBook { /// friends: HashSet, /// } /// /// #[derive(Arbitrary, Hash, Eq, PartialEq)] /// pub enum Friend { /// Buddy { name: String }, /// Pal { age: usize }, /// } /// # } /// ``` /// /// Every member of the `struct` or `enum` must also implement `Arbitrary`. /// /// # Implementing `Arbitrary` By Hand /// /// Implementing `Arbitrary` mostly involves nested calls to other `Arbitrary` /// arbitrary implementations for each of your `struct` or `enum`'s members. But /// sometimes you need some amount of raw data, or you need to generate a /// variably-sized collection type, or you something of that sort. The /// [`Unstructured`][crate::Unstructured] type helps you with these tasks. /// /// ``` /// # #[cfg(feature = "derive")] mod foo { /// # pub struct MyCollection { _t: std::marker::PhantomData } /// # impl MyCollection { /// # pub fn new() -> Self { MyCollection { _t: std::marker::PhantomData } } /// # pub fn insert(&mut self, element: T) {} /// # } /// use arbitrary::{Arbitrary, Result, Unstructured}; /// /// impl<'a, T> Arbitrary<'a> for MyCollection /// where /// T: Arbitrary<'a>, /// { /// fn arbitrary(u: &mut Unstructured<'a>) -> Result { /// // Get an iterator of arbitrary `T`s. /// let iter = u.arbitrary_iter::()?; /// /// // And then create a collection! /// let mut my_collection = MyCollection::new(); /// for elem_result in iter { /// let elem = elem_result?; /// my_collection.insert(elem); /// } /// /// Ok(my_collection) /// } /// } /// # } /// ``` pub trait Arbitrary<'a>: Sized { /// Generate an arbitrary value of `Self` from the given unstructured data. /// /// Calling `Arbitrary::arbitrary` requires that you have some raw data, /// perhaps given to you by a fuzzer like AFL or libFuzzer. You wrap this /// raw data in an `Unstructured`, and then you can call `::arbitrary` to construct an arbitrary instance of `MyType` /// from that unstuctured data. /// /// Implementation may return an error if there is not enough data to /// construct a full instance of `Self`. This is generally OK: it is better /// to exit early and get the fuzzer to provide more input data, than it is /// to generate default values in place of the missing data, which would /// bias the distribution of generated values, and ultimately make fuzzing /// less efficient. /// /// ``` /// # #[cfg(feature = "derive")] fn foo() { /// use arbitrary::{Arbitrary, Unstructured}; /// /// #[derive(Arbitrary)] /// pub struct MyType { /// // ... /// } /// /// // Get the raw data from the fuzzer or wherever else. /// # let get_raw_data_from_fuzzer = || &[]; /// let raw_data: &[u8] = get_raw_data_from_fuzzer(); /// /// // Wrap that raw data in an `Unstructured`. /// let mut unstructured = Unstructured::new(raw_data); /// /// // Generate an arbitrary instance of `MyType` and do stuff with it. /// if let Ok(value) = MyType::arbitrary(&mut unstructured) { /// # let do_stuff = |_| {}; /// do_stuff(value); /// } /// # } /// ``` /// /// See also the documentation for [`Unstructured`][crate::Unstructured]. fn arbitrary(u: &mut Unstructured<'a>) -> Result; /// Generate an arbitrary value of `Self` from the entirety of the given unstructured data. /// /// This is similar to Arbitrary::arbitrary, however it assumes that it is the /// last consumer of the given data, and is thus able to consume it all if it needs. /// See also the documentation for [`Unstructured`][crate::Unstructured]. fn arbitrary_take_rest(mut u: Unstructured<'a>) -> Result { Self::arbitrary(&mut u) } /// Get a size hint for how many bytes out of an `Unstructured` this type /// needs to construct itself. /// /// This is useful for determining how many elements we should insert when /// creating an arbitrary collection. /// /// The return value is similar to /// [`Iterator::size_hint`][iterator-size-hint]: it returns a tuple where /// the first element is a lower bound on the number of bytes required, and /// the second element is an optional upper bound. /// /// The default implementation return `(0, None)` which is correct for any /// type, but not ultimately that useful. Using `#[derive(Arbitrary)]` will /// create a better implementation. If you are writing an `Arbitrary` /// implementation by hand, and your type can be part of a dynamically sized /// collection (such as `Vec`), you are strongly encouraged to override this /// default with a better implementation. The /// [`size_hint`][crate::size_hint] module will help with this task. /// /// ## The `depth` Parameter /// /// If you 100% know that the type you are implementing `Arbitrary` for is /// not a recursive type, or your implementation is not transitively calling /// any other `size_hint` methods, you can ignore the `depth` parameter. /// Note that if you are implementing `Arbitrary` for a generic type, you /// cannot guarantee the lack of type recrusion! /// /// Otherwise, you need to use /// [`arbitrary::size_hint::recursion_guard(depth)`][crate::size_hint::recursion_guard] /// to prevent potential infinite recursion when calculating size hints for /// potentially recursive types: /// /// ``` /// use arbitrary::{Arbitrary, Unstructured, size_hint}; /// /// // This can potentially be a recursive type if `L` or `R` contain /// // something like `Box>>`! /// enum MyEither { /// Left(L), /// Right(R), /// } /// /// impl<'a, L, R> Arbitrary<'a> for MyEither /// where /// L: Arbitrary<'a>, /// R: Arbitrary<'a>, /// { /// fn arbitrary(u: &mut Unstructured) -> arbitrary::Result { /// // ... /// # unimplemented!() /// } /// /// fn size_hint(depth: usize) -> (usize, Option) { /// // Protect against potential infinite recursion with /// // `recursion_guard`. /// size_hint::recursion_guard(depth, |depth| { /// // If we aren't too deep, then `recursion_guard` calls /// // this closure, which implements the natural size hint. /// // Don't forget to use the new `depth` in all nested /// // `size_hint` calls! We recommend shadowing the /// // parameter, like what is done here, so that you can't /// // accidentally use the wrong depth. /// size_hint::or( /// ::size_hint(depth), /// ::size_hint(depth), /// ) /// }) /// } /// } /// ``` /// /// [iterator-size-hint]: https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html#method.size_hint #[inline] fn size_hint(depth: usize) -> (usize, Option) { let _ = depth; (0, None) } } impl<'a> Arbitrary<'a> for () { fn arbitrary(_: &mut Unstructured<'a>) -> Result { Ok(()) } #[inline] fn size_hint(_depth: usize) -> (usize, Option) { (0, Some(0)) } } impl<'a> Arbitrary<'a> for bool { fn arbitrary(u: &mut Unstructured<'a>) -> Result { Ok(>::arbitrary(u)? & 1 == 1) } #[inline] fn size_hint(depth: usize) -> (usize, Option) { >::size_hint(depth) } } macro_rules! impl_arbitrary_for_integers { ( $( $ty:ty: $unsigned:ty; )* ) => { $( impl<'a> Arbitrary<'a> for $ty { fn arbitrary(u: &mut Unstructured<'a>) -> Result { let mut buf = [0; mem::size_of::<$ty>()]; u.fill_buffer(&mut buf)?; let mut x: $unsigned = 0; for i in 0..mem::size_of::<$ty>() { x |= buf[i] as $unsigned << (i * 8); } Ok(x as $ty) } #[inline] fn size_hint(_depth: usize) -> (usize, Option) { let n = mem::size_of::<$ty>(); (n, Some(n)) } } )* } } impl_arbitrary_for_integers! { u8: u8; u16: u16; u32: u32; u64: u64; u128: u128; usize: usize; i8: u8; i16: u16; i32: u32; i64: u64; i128: u128; isize: usize; } macro_rules! impl_arbitrary_for_floats { ( $( $ty:ident : $unsigned:ty; )* ) => { $( impl<'a> Arbitrary<'a> for $ty { fn arbitrary(u: &mut Unstructured<'a>) -> Result { Ok(Self::from_bits(<$unsigned as Arbitrary<'a>>::arbitrary(u)?)) } #[inline] fn size_hint(depth: usize) -> (usize, Option) { <$unsigned as Arbitrary<'a>>::size_hint(depth) } } )* } } impl_arbitrary_for_floats! { f32: u32; f64: u64; } impl<'a> Arbitrary<'a> for char { fn arbitrary(u: &mut Unstructured<'a>) -> Result { use std::char; const CHAR_END: u32 = 0x0011_000; // The size of the surrogate blocks const SURROGATES_START: u32 = 0xD800; let mut c = >::arbitrary(u)? % CHAR_END; if let Some(c) = char::from_u32(c) { return Ok(c); } else { // We found a surrogate, wrap and try again c -= SURROGATES_START; Ok(char::from_u32(c) .expect("Generated character should be valid! This is a bug in arbitrary-rs")) } } #[inline] fn size_hint(depth: usize) -> (usize, Option) { >::size_hint(depth) } } impl<'a> Arbitrary<'a> for AtomicBool { fn arbitrary(u: &mut Unstructured<'a>) -> Result { Arbitrary::arbitrary(u).map(Self::new) } #[inline] fn size_hint(depth: usize) -> (usize, Option) { >::size_hint(depth) } } impl<'a> Arbitrary<'a> for AtomicIsize { fn arbitrary(u: &mut Unstructured<'a>) -> Result { Arbitrary::arbitrary(u).map(Self::new) } #[inline] fn size_hint(depth: usize) -> (usize, Option) { >::size_hint(depth) } } impl<'a> Arbitrary<'a> for AtomicUsize { fn arbitrary(u: &mut Unstructured<'a>) -> Result { Arbitrary::arbitrary(u).map(Self::new) } #[inline] fn size_hint(depth: usize) -> (usize, Option) { >::size_hint(depth) } } macro_rules! impl_range { ( $range:ty, $value_closure:expr, $value_ty:ty, $fun:ident($fun_closure:expr), $size_hint_closure:expr ) => { impl<'a, A> Arbitrary<'a> for $range where A: Arbitrary<'a> + Clone + PartialOrd, { fn arbitrary(u: &mut Unstructured<'a>) -> Result { let value: $value_ty = Arbitrary::arbitrary(u)?; Ok($fun(value, $fun_closure)) } #[inline] fn size_hint(depth: usize) -> (usize, Option) { $size_hint_closure(depth) } } }; } impl_range!( Range, |r: &Range| (r.start.clone(), r.end.clone()), (A, A), bounded_range(|(a, b)| a..b), |depth| crate::size_hint::and( ::size_hint(depth), ::size_hint(depth) ) ); impl_range!( RangeFrom, |r: &RangeFrom| r.start.clone(), A, unbounded_range(|a| a..), |depth| ::size_hint(depth) ); impl_range!( RangeInclusive, |r: &RangeInclusive| (r.start().clone(), r.end().clone()), (A, A), bounded_range(|(a, b)| a..=b), |depth| crate::size_hint::and( ::size_hint(depth), ::size_hint(depth) ) ); impl_range!( RangeTo, |r: &RangeTo| r.end.clone(), A, unbounded_range(|b| ..b), |depth| ::size_hint(depth) ); impl_range!( RangeToInclusive, |r: &RangeToInclusive| r.end.clone(), A, unbounded_range(|b| ..=b), |depth| ::size_hint(depth) ); pub(crate) fn bounded_range(bounds: (I, I), cb: CB) -> R where CB: Fn((I, I)) -> R, I: PartialOrd, R: RangeBounds, { let (mut start, mut end) = bounds; if start > end { mem::swap(&mut start, &mut end); } cb((start, end)) } pub(crate) fn unbounded_range(bound: I, cb: CB) -> R where CB: Fn(I) -> R, R: RangeBounds, { cb(bound) } impl<'a> Arbitrary<'a> for Duration { fn arbitrary(u: &mut Unstructured<'a>) -> Result { Ok(Self::new( ::arbitrary(u)?, u.int_in_range(0..=999_999_999)?, )) } #[inline] fn size_hint(depth: usize) -> (usize, Option) { crate::size_hint::and( ::size_hint(depth), ::size_hint(depth), ) } } impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Option { fn arbitrary(u: &mut Unstructured<'a>) -> Result { Ok(if >::arbitrary(u)? { Some(Arbitrary::arbitrary(u)?) } else { None }) } #[inline] fn size_hint(depth: usize) -> (usize, Option) { crate::size_hint::and( ::size_hint(depth), crate::size_hint::or((0, Some(0)), ::size_hint(depth)), ) } } impl<'a, A: Arbitrary<'a>, B: Arbitrary<'a>> Arbitrary<'a> for std::result::Result { fn arbitrary(u: &mut Unstructured<'a>) -> Result { Ok(if >::arbitrary(u)? { Ok(::arbitrary(u)?) } else { Err(::arbitrary(u)?) }) } #[inline] fn size_hint(depth: usize) -> (usize, Option) { crate::size_hint::and( ::size_hint(depth), crate::size_hint::or( ::size_hint(depth), ::size_hint(depth), ), ) } } macro_rules! arbitrary_tuple { () => {}; ($last: ident $($xs: ident)*) => { arbitrary_tuple!($($xs)*); impl<'a, $($xs: Arbitrary<'a>,)* $last: Arbitrary<'a>> Arbitrary<'a> for ($($xs,)* $last,) { fn arbitrary(u: &mut Unstructured<'a>) -> Result { Ok(($($xs::arbitrary(u)?,)* Arbitrary::arbitrary(u)?,)) } #[allow(unused_mut, non_snake_case)] fn arbitrary_take_rest(mut u: Unstructured<'a>) -> Result { $(let $xs = $xs::arbitrary(&mut u)?;)* let $last = $last::arbitrary_take_rest(u)?; Ok(($($xs,)* $last,)) } #[inline] fn size_hint(depth: usize) -> (usize, Option) { crate::size_hint::and_all(&[ <$last as Arbitrary>::size_hint(depth), $( <$xs as Arbitrary>::size_hint(depth) ),* ]) } } }; } arbitrary_tuple!(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z); macro_rules! arbitrary_array { {$n:expr, ($t:ident, $a:ident) $(($ts:ident, $as:ident))*} => { arbitrary_array!{($n - 1), $(($ts, $as))*} impl<'a, T: Arbitrary<'a>> Arbitrary<'a> for [T; $n] { fn arbitrary(u: &mut Unstructured<'a>) -> Result<[T; $n]> { Ok([ Arbitrary::arbitrary(u)?, $(<$ts as Arbitrary>::arbitrary(u)?),* ]) } #[allow(unused_mut)] fn arbitrary_take_rest(mut u: Unstructured<'a>) -> Result<[T; $n]> { $(let $as = $ts::arbitrary(&mut u)?;)* let last = Arbitrary::arbitrary_take_rest(u)?; Ok([ $($as,)* last ]) } #[inline] fn size_hint(depth: usize) -> (usize, Option) { crate::size_hint::and_all(&[ <$t as Arbitrary>::size_hint(depth), $( <$ts as Arbitrary>::size_hint(depth) ),* ]) } } }; ($n: expr,) => {}; } impl<'a, T: Arbitrary<'a>> Arbitrary<'a> for [T; 0] { fn arbitrary(_: &mut Unstructured<'a>) -> Result<[T; 0]> { Ok([]) } fn arbitrary_take_rest(_: Unstructured<'a>) -> Result<[T; 0]> { Ok([]) } #[inline] fn size_hint(_: usize) -> (usize, Option) { crate::size_hint::and_all(&[]) } } arbitrary_array! { 32, (T, a) (T, b) (T, c) (T, d) (T, e) (T, f) (T, g) (T, h) (T, i) (T, j) (T, k) (T, l) (T, m) (T, n) (T, o) (T, p) (T, q) (T, r) (T, s) (T, u) (T, v) (T, w) (T, x) (T, y) (T, z) (T, aa) (T, ab) (T, ac) (T, ad) (T, ae) (T, af) (T, ag) } impl<'a> Arbitrary<'a> for &'a [u8] { fn arbitrary(u: &mut Unstructured<'a>) -> Result { let len = u.arbitrary_len::()?; u.bytes(len) } fn arbitrary_take_rest(u: Unstructured<'a>) -> Result { Ok(u.take_rest()) } #[inline] fn size_hint(depth: usize) -> (usize, Option) { ::size_hint(depth) } } impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Vec { fn arbitrary(u: &mut Unstructured<'a>) -> Result { u.arbitrary_iter()?.collect() } fn arbitrary_take_rest(u: Unstructured<'a>) -> Result { u.arbitrary_take_rest_iter()?.collect() } #[inline] fn size_hint(depth: usize) -> (usize, Option) { crate::size_hint::and(::size_hint(depth), (0, None)) } } impl<'a, K: Arbitrary<'a> + Ord, V: Arbitrary<'a>> Arbitrary<'a> for BTreeMap { fn arbitrary(u: &mut Unstructured<'a>) -> Result { u.arbitrary_iter()?.collect() } fn arbitrary_take_rest(u: Unstructured<'a>) -> Result { u.arbitrary_take_rest_iter()?.collect() } #[inline] fn size_hint(depth: usize) -> (usize, Option) { crate::size_hint::and(::size_hint(depth), (0, None)) } } impl<'a, A: Arbitrary<'a> + Ord> Arbitrary<'a> for BTreeSet { fn arbitrary(u: &mut Unstructured<'a>) -> Result { u.arbitrary_iter()?.collect() } fn arbitrary_take_rest(u: Unstructured<'a>) -> Result { u.arbitrary_take_rest_iter()?.collect() } #[inline] fn size_hint(depth: usize) -> (usize, Option) { crate::size_hint::and(::size_hint(depth), (0, None)) } } impl<'a, A: Arbitrary<'a> + Ord> Arbitrary<'a> for BinaryHeap { fn arbitrary(u: &mut Unstructured<'a>) -> Result { u.arbitrary_iter()?.collect() } fn arbitrary_take_rest(u: Unstructured<'a>) -> Result { u.arbitrary_take_rest_iter()?.collect() } #[inline] fn size_hint(depth: usize) -> (usize, Option) { crate::size_hint::and(::size_hint(depth), (0, None)) } } impl<'a, K: Arbitrary<'a> + Eq + ::std::hash::Hash, V: Arbitrary<'a>> Arbitrary<'a> for HashMap { fn arbitrary(u: &mut Unstructured<'a>) -> Result { u.arbitrary_iter()?.collect() } fn arbitrary_take_rest(u: Unstructured<'a>) -> Result { u.arbitrary_take_rest_iter()?.collect() } #[inline] fn size_hint(depth: usize) -> (usize, Option) { crate::size_hint::and(::size_hint(depth), (0, None)) } } impl<'a, A: Arbitrary<'a> + Eq + ::std::hash::Hash> Arbitrary<'a> for HashSet { fn arbitrary(u: &mut Unstructured<'a>) -> Result { u.arbitrary_iter()?.collect() } fn arbitrary_take_rest(u: Unstructured<'a>) -> Result { u.arbitrary_take_rest_iter()?.collect() } #[inline] fn size_hint(depth: usize) -> (usize, Option) { crate::size_hint::and(::size_hint(depth), (0, None)) } } impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for LinkedList { fn arbitrary(u: &mut Unstructured<'a>) -> Result { u.arbitrary_iter()?.collect() } fn arbitrary_take_rest(u: Unstructured<'a>) -> Result { u.arbitrary_take_rest_iter()?.collect() } #[inline] fn size_hint(depth: usize) -> (usize, Option) { crate::size_hint::and(::size_hint(depth), (0, None)) } } impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for VecDeque { fn arbitrary(u: &mut Unstructured<'a>) -> Result { u.arbitrary_iter()?.collect() } fn arbitrary_take_rest(u: Unstructured<'a>) -> Result { u.arbitrary_take_rest_iter()?.collect() } #[inline] fn size_hint(depth: usize) -> (usize, Option) { crate::size_hint::and(::size_hint(depth), (0, None)) } } impl<'a, A> Arbitrary<'a> for Cow<'a, A> where A: ToOwned + ?Sized, ::Owned: Arbitrary<'a>, { fn arbitrary(u: &mut Unstructured<'a>) -> Result { Arbitrary::arbitrary(u).map(Cow::Owned) } #[inline] fn size_hint(depth: usize) -> (usize, Option) { crate::size_hint::recursion_guard(depth, |depth| { <::Owned as Arbitrary>::size_hint(depth) }) } } impl<'a> Arbitrary<'a> for &'a str { fn arbitrary(u: &mut Unstructured<'a>) -> Result { let size = u.arbitrary_len::()?; match str::from_utf8(&u.peek_bytes(size).unwrap()) { Ok(s) => { u.bytes(size).unwrap(); Ok(s) } Err(e) => { let i = e.valid_up_to(); let valid = u.bytes(i).unwrap(); let s = unsafe { debug_assert!(str::from_utf8(valid).is_ok()); str::from_utf8_unchecked(valid) }; Ok(s) } } } fn arbitrary_take_rest(u: Unstructured<'a>) -> Result { let bytes = u.take_rest(); str::from_utf8(bytes) .map_err(|_| Error::IncorrectFormat) .map(Into::into) } #[inline] fn size_hint(depth: usize) -> (usize, Option) { crate::size_hint::and(::size_hint(depth), (0, None)) } } impl<'a> Arbitrary<'a> for String { fn arbitrary(u: &mut Unstructured<'a>) -> Result { <&str as Arbitrary>::arbitrary(u).map(Into::into) } fn arbitrary_take_rest(u: Unstructured<'a>) -> Result { <&str as Arbitrary>::arbitrary_take_rest(u).map(Into::into) } #[inline] fn size_hint(depth: usize) -> (usize, Option) { <&str as Arbitrary>::size_hint(depth) } } impl<'a> Arbitrary<'a> for CString { fn arbitrary(u: &mut Unstructured<'a>) -> Result { as Arbitrary>::arbitrary(u).map(|mut x| { x.retain(|&c| c != 0); Self::new(x).unwrap() }) } #[inline] fn size_hint(depth: usize) -> (usize, Option) { as Arbitrary>::size_hint(depth) } } impl<'a> Arbitrary<'a> for OsString { fn arbitrary(u: &mut Unstructured<'a>) -> Result { ::arbitrary(u).map(From::from) } #[inline] fn size_hint(depth: usize) -> (usize, Option) { ::size_hint(depth) } } impl<'a> Arbitrary<'a> for PathBuf { fn arbitrary(u: &mut Unstructured<'a>) -> Result { ::arbitrary(u).map(From::from) } #[inline] fn size_hint(depth: usize) -> (usize, Option) { ::size_hint(depth) } } impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Box { fn arbitrary(u: &mut Unstructured<'a>) -> Result { Arbitrary::arbitrary(u).map(Self::new) } #[inline] fn size_hint(depth: usize) -> (usize, Option) { crate::size_hint::recursion_guard(depth, |depth| ::size_hint(depth)) } } impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Box<[A]> { fn arbitrary(u: &mut Unstructured<'a>) -> Result { as Arbitrary>::arbitrary(u).map(|x| x.into_boxed_slice()) } #[inline] fn size_hint(depth: usize) -> (usize, Option) { as Arbitrary>::size_hint(depth) } } impl<'a> Arbitrary<'a> for Box { fn arbitrary(u: &mut Unstructured<'a>) -> Result { ::arbitrary(u).map(|x| x.into_boxed_str()) } #[inline] fn size_hint(depth: usize) -> (usize, Option) { ::size_hint(depth) } } // impl Arbitrary for Box { // fn arbitrary(u: &mut Unstructured<'_>) -> Result { // ::arbitrary(u).map(|x| x.into_boxed_c_str()) // } // } // impl Arbitrary for Box { // fn arbitrary(u: &mut Unstructured<'_>) -> Result { // ::arbitrary(u).map(|x| x.into_boxed_osstr()) // // } // } impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Arc { fn arbitrary(u: &mut Unstructured<'a>) -> Result { Arbitrary::arbitrary(u).map(Self::new) } #[inline] fn size_hint(depth: usize) -> (usize, Option) { crate::size_hint::recursion_guard(depth, |depth| ::size_hint(depth)) } } impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Rc { fn arbitrary(u: &mut Unstructured<'a>) -> Result { Arbitrary::arbitrary(u).map(Self::new) } #[inline] fn size_hint(depth: usize) -> (usize, Option) { crate::size_hint::recursion_guard(depth, |depth| ::size_hint(depth)) } } impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Cell { fn arbitrary(u: &mut Unstructured<'a>) -> Result { Arbitrary::arbitrary(u).map(Self::new) } #[inline] fn size_hint(depth: usize) -> (usize, Option) { >::size_hint(depth) } } impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for RefCell { fn arbitrary(u: &mut Unstructured<'a>) -> Result { Arbitrary::arbitrary(u).map(Self::new) } #[inline] fn size_hint(depth: usize) -> (usize, Option) { >::size_hint(depth) } } impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for UnsafeCell { fn arbitrary(u: &mut Unstructured<'a>) -> Result { Arbitrary::arbitrary(u).map(Self::new) } #[inline] fn size_hint(depth: usize) -> (usize, Option) { >::size_hint(depth) } } impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Mutex { fn arbitrary(u: &mut Unstructured<'a>) -> Result { Arbitrary::arbitrary(u).map(Self::new) } #[inline] fn size_hint(depth: usize) -> (usize, Option) { >::size_hint(depth) } } impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for iter::Empty { fn arbitrary(_: &mut Unstructured<'a>) -> Result { Ok(iter::empty()) } #[inline] fn size_hint(_depth: usize) -> (usize, Option) { (0, Some(0)) } } impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for ::std::marker::PhantomData { fn arbitrary(_: &mut Unstructured<'a>) -> Result { Ok(::std::marker::PhantomData) } #[inline] fn size_hint(_depth: usize) -> (usize, Option) { (0, Some(0)) } } impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for ::std::num::Wrapping { fn arbitrary(u: &mut Unstructured<'a>) -> Result { Arbitrary::arbitrary(u).map(::std::num::Wrapping) } #[inline] fn size_hint(depth: usize) -> (usize, Option) { >::size_hint(depth) } } #[cfg(test)] mod test { use super::*; #[test] fn finite_buffer_fill_buffer() { let x = [1, 2, 3, 4]; let mut rb = Unstructured::new(&x); let mut z = [0; 2]; rb.fill_buffer(&mut z).unwrap(); assert_eq!(z, [1, 2]); rb.fill_buffer(&mut z).unwrap(); assert_eq!(z, [3, 4]); rb.fill_buffer(&mut z).unwrap(); assert_eq!(z, [0, 0]); } #[test] fn arbitrary_for_integers() { let x = [1, 2, 3, 4]; let mut buf = Unstructured::new(&x); let expected = 1 | (2 << 8) | (3 << 16) | (4 << 24); let actual = i32::arbitrary(&mut buf).unwrap(); assert_eq!(expected, actual); } #[test] fn arbitrary_for_bytes() { let x = [1, 2, 3, 4, 4]; let mut buf = Unstructured::new(&x); let expected = &[1, 2, 3, 4]; let actual = <&[u8] as Arbitrary>::arbitrary(&mut buf).unwrap(); assert_eq!(expected, actual); } #[test] fn arbitrary_take_rest_for_bytes() { let x = [1, 2, 3, 4]; let buf = Unstructured::new(&x); let expected = &[1, 2, 3, 4]; let actual = <&[u8] as Arbitrary>::arbitrary_take_rest(buf).unwrap(); assert_eq!(expected, actual); } #[test] fn arbitrary_collection() { let x = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, ]; assert_eq!( Vec::::arbitrary(&mut Unstructured::new(&x)).unwrap(), &[2, 4, 6, 8, 1] ); assert_eq!( Vec::::arbitrary(&mut Unstructured::new(&x)).unwrap(), &[84148994] ); assert_eq!( String::arbitrary(&mut Unstructured::new(&x)).unwrap(), "\x01\x02\x03\x04\x05\x06\x07\x08" ); } #[test] fn arbitrary_take_rest() { let x = [1, 2, 3, 4]; assert_eq!( Vec::::arbitrary_take_rest(Unstructured::new(&x)).unwrap(), &[1, 2, 3, 4] ); assert_eq!( Vec::::arbitrary_take_rest(Unstructured::new(&x)).unwrap(), &[0x4030201] ); assert_eq!( String::arbitrary_take_rest(Unstructured::new(&x)).unwrap(), "\x01\x02\x03\x04" ); } #[test] fn size_hint_for_tuples() { assert_eq!( (7, Some(7)), <(bool, u16, i32) as Arbitrary<'_>>::size_hint(0) ); assert_eq!( (1 + mem::size_of::(), None), <(u8, Vec) as Arbitrary>::size_hint(0) ); } }