Coverage Report

Created: 2025-06-16 06:13

/rust/registry/src/index.crates.io-6f17d22bba15001f/arbitrary-1.4.1/src/lib.rs
Line
Count
Source (jump to first uncovered line)
1
// Copyright © 2019 The Rust Fuzz Project Developers.
2
//
3
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6
// option. This file may not be copied, modified, or distributed
7
// except according to those terms.
8
9
//! The `Arbitrary` trait crate.
10
//!
11
//! This trait provides an [`Arbitrary`] trait to
12
//! produce well-typed, structured values, from raw, byte buffers. It is
13
//! generally intended to be used with fuzzers like AFL or libFuzzer. See the
14
//! [`Arbitrary`] trait's documentation for details on
15
//! automatically deriving, implementing, and/or using the trait.
16
17
#![deny(bad_style)]
18
#![deny(missing_docs)]
19
#![deny(future_incompatible)]
20
#![deny(nonstandard_style)]
21
#![deny(rust_2018_compatibility)]
22
#![deny(rust_2018_idioms)]
23
#![deny(unused)]
24
25
mod error;
26
mod foreign;
27
pub mod size_hint;
28
pub mod unstructured;
29
30
#[cfg(test)]
31
mod tests;
32
33
pub use error::*;
34
35
#[cfg(feature = "derive_arbitrary")]
36
pub use derive_arbitrary::*;
37
38
#[doc(inline)]
39
pub use unstructured::Unstructured;
40
41
/// Error indicating that the maximum recursion depth has been reached while calculating [`Arbitrary::size_hint`]()
42
#[derive(Debug, Clone)]
43
#[non_exhaustive]
44
pub struct MaxRecursionReached {}
45
46
impl core::fmt::Display for MaxRecursionReached {
47
0
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
48
0
        f.write_str("Maximum recursion depth has been reached")
49
0
    }
50
}
51
52
impl std::error::Error for MaxRecursionReached {}
53
54
/// Generate arbitrary structured values from raw, unstructured data.
55
///
56
/// The `Arbitrary` trait allows you to generate valid structured values, like
57
/// `HashMap`s, or ASTs, or `MyTomlConfig`, or any other data structure from
58
/// raw, unstructured bytes provided by a fuzzer.
59
///
60
/// # Deriving `Arbitrary`
61
///
62
/// Automatically deriving the `Arbitrary` trait is the recommended way to
63
/// implement `Arbitrary` for your types.
64
///
65
/// Using the custom derive requires that you enable the `"derive"` cargo
66
/// feature in your `Cargo.toml`:
67
///
68
/// ```toml
69
/// [dependencies]
70
/// arbitrary = { version = "1", features = ["derive"] }
71
/// ```
72
///
73
/// Then, you add the `#[derive(Arbitrary)]` annotation to your `struct` or
74
/// `enum` type definition:
75
///
76
/// ```
77
/// # #[cfg(feature = "derive")] mod foo {
78
/// use arbitrary::Arbitrary;
79
/// use std::collections::HashSet;
80
///
81
/// #[derive(Arbitrary)]
82
/// pub struct AddressBook {
83
///     friends: HashSet<Friend>,
84
/// }
85
///
86
/// #[derive(Arbitrary, Hash, Eq, PartialEq)]
87
/// pub enum Friend {
88
///     Buddy { name: String },
89
///     Pal { age: usize },
90
/// }
91
/// # }
92
/// ```
93
///
94
/// Every member of the `struct` or `enum` must also implement `Arbitrary`.
95
///
96
/// It is also possible to change the default bounds added by the derive:
97
///
98
/// ```
99
/// # #[cfg(feature = "derive")] mod foo {
100
/// use arbitrary::Arbitrary;
101
///
102
/// trait Trait {
103
///     type Assoc: for<'a> Arbitrary<'a>;
104
/// }
105
///
106
/// #[derive(Arbitrary)]
107
/// // The bounds are used verbatim, so any existing trait bounds will need to be repeated.
108
/// #[arbitrary(bound = "T: Trait")]
109
/// struct Point<T: Trait> {
110
///     x: T::Assoc,
111
/// }
112
/// # }
113
/// ```
114
///
115
/// # Implementing `Arbitrary` By Hand
116
///
117
/// Implementing `Arbitrary` mostly involves nested calls to other `Arbitrary`
118
/// arbitrary implementations for each of your `struct` or `enum`'s members. But
119
/// sometimes you need some amount of raw data, or you need to generate a
120
/// variably-sized collection type, or something of that sort. The
121
/// [`Unstructured`] type helps you with these tasks.
122
///
123
/// ```
124
/// # #[cfg(feature = "derive")] mod foo {
125
/// # pub struct MyCollection<T> { _t: std::marker::PhantomData<T> }
126
/// # impl<T> MyCollection<T> {
127
/// #     pub fn new() -> Self { MyCollection { _t: std::marker::PhantomData } }
128
/// #     pub fn insert(&mut self, element: T) {}
129
/// # }
130
/// use arbitrary::{Arbitrary, Result, Unstructured};
131
///
132
/// impl<'a, T> Arbitrary<'a> for MyCollection<T>
133
/// where
134
///     T: Arbitrary<'a>,
135
/// {
136
///     fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
137
///         // Get an iterator of arbitrary `T`s.
138
///         let iter = u.arbitrary_iter::<T>()?;
139
///
140
///         // And then create a collection!
141
///         let mut my_collection = MyCollection::new();
142
///         for elem_result in iter {
143
///             let elem = elem_result?;
144
///             my_collection.insert(elem);
145
///         }
146
///
147
///         Ok(my_collection)
148
///     }
149
/// }
150
/// # }
151
/// ```
152
///
153
/// # A Note On Output Distributions
154
///
155
/// There is no requirement for a particular distribution of the values. For
156
/// example, it is not required that every value appears with the same
157
/// probability. That being said, the main use for `Arbitrary` is for fuzzing,
158
/// so in many cases a uniform distribution will make the most sense in order to
159
/// provide the best coverage of the domain. In other cases this is not
160
/// desirable or even possible, for example when sampling from a uniform
161
/// distribution is computationally expensive or in the case of collections that
162
/// may grow indefinitely.
163
pub trait Arbitrary<'a>: Sized {
164
    /// Generate an arbitrary value of `Self` from the given unstructured data.
165
    ///
166
    /// Calling `Arbitrary::arbitrary` requires that you have some raw data,
167
    /// perhaps given to you by a fuzzer like AFL or libFuzzer. You wrap this
168
    /// raw data in an `Unstructured`, and then you can call `<MyType as
169
    /// Arbitrary>::arbitrary` to construct an arbitrary instance of `MyType`
170
    /// from that unstructured data.
171
    ///
172
    /// Implementations may return an error if there is not enough data to
173
    /// construct a full instance of `Self`, or they may fill out the rest of
174
    /// `Self` with dummy values. Using dummy values when the underlying data is
175
    /// exhausted can help avoid accidentally "defeating" some of the fuzzer's
176
    /// mutations to the underlying byte stream that might otherwise lead to
177
    /// interesting runtime behavior or new code coverage if only we had just a
178
    /// few more bytes. However, it also requires that implementations for
179
    /// recursive types (e.g. `struct Foo(Option<Box<Foo>>)`) avoid infinite
180
    /// recursion when the underlying data is exhausted.
181
    ///
182
    /// ```
183
    /// # #[cfg(feature = "derive")] fn foo() {
184
    /// use arbitrary::{Arbitrary, Unstructured};
185
    ///
186
    /// #[derive(Arbitrary)]
187
    /// pub struct MyType {
188
    ///     // ...
189
    /// }
190
    ///
191
    /// // Get the raw data from the fuzzer or wherever else.
192
    /// # let get_raw_data_from_fuzzer = || &[];
193
    /// let raw_data: &[u8] = get_raw_data_from_fuzzer();
194
    ///
195
    /// // Wrap that raw data in an `Unstructured`.
196
    /// let mut unstructured = Unstructured::new(raw_data);
197
    ///
198
    /// // Generate an arbitrary instance of `MyType` and do stuff with it.
199
    /// if let Ok(value) = MyType::arbitrary(&mut unstructured) {
200
    /// #   let do_stuff = |_| {};
201
    ///     do_stuff(value);
202
    /// }
203
    /// # }
204
    /// ```
205
    ///
206
    /// See also the documentation for [`Unstructured`].
207
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self>;
208
209
    /// Generate an arbitrary value of `Self` from the entirety of the given
210
    /// unstructured data.
211
    ///
212
    /// This is similar to Arbitrary::arbitrary, however it assumes that it is
213
    /// the last consumer of the given data, and is thus able to consume it all
214
    /// if it needs.  See also the documentation for
215
    /// [`Unstructured`].
216
0
    fn arbitrary_take_rest(mut u: Unstructured<'a>) -> Result<Self> {
217
0
        Self::arbitrary(&mut u)
218
0
    }
219
220
    /// Get a size hint for how many bytes out of an `Unstructured` this type
221
    /// needs to construct itself.
222
    ///
223
    /// This is useful for determining how many elements we should insert when
224
    /// creating an arbitrary collection.
225
    ///
226
    /// The return value is similar to [`Iterator::size_hint`]: it returns a
227
    /// tuple where the first element is a lower bound on the number of bytes
228
    /// required, and the second element is an optional upper bound.
229
    ///
230
    /// The default implementation return `(0, None)` which is correct for any
231
    /// type, but not ultimately that useful. Using `#[derive(Arbitrary)]` will
232
    /// create a better implementation. If you are writing an `Arbitrary`
233
    /// implementation by hand, and your type can be part of a dynamically sized
234
    /// collection (such as `Vec`), you are strongly encouraged to override this
235
    /// default with a better implementation, and also override
236
    /// [`try_size_hint`].
237
    ///
238
    /// ## How to implement this
239
    ///
240
    /// If the size hint calculation is a trivial constant and does not recurse
241
    /// into any other `size_hint` call, you should implement it in `size_hint`:
242
    ///
243
    /// ```
244
    /// use arbitrary::{size_hint, Arbitrary, Result, Unstructured};
245
    ///
246
    /// struct SomeStruct(u8);
247
    ///
248
    /// impl<'a> Arbitrary<'a> for SomeStruct {
249
    ///     fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
250
    ///         let buf = &mut [0];
251
    ///         u.fill_buffer(buf)?;
252
    ///         Ok(SomeStruct(buf[0]))
253
    ///     }
254
    ///
255
    ///     #[inline]
256
    ///     fn size_hint(depth: usize) -> (usize, Option<usize>) {
257
    ///         let _ = depth;
258
    ///         (1, Some(1))
259
    ///     }
260
    /// }
261
    /// ```
262
    ///
263
    /// Otherwise, it should instead be implemented in [`try_size_hint`],
264
    /// and the `size_hint` implementation should forward to it:
265
    ///
266
    /// ```
267
    /// use arbitrary::{size_hint, Arbitrary, MaxRecursionReached, Result, Unstructured};
268
    ///
269
    /// struct SomeStruct<A, B> {
270
    ///     a: A,
271
    ///     b: B,
272
    /// }
273
    ///
274
    /// impl<'a, A: Arbitrary<'a>, B: Arbitrary<'a>> Arbitrary<'a> for SomeStruct<A, B> {
275
    ///     fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
276
    ///         // ...
277
    /// #       todo!()
278
    ///     }
279
    ///
280
    ///     fn size_hint(depth: usize) -> (usize, Option<usize>) {
281
    ///         // Return the value of try_size_hint
282
    ///         //
283
    ///         // If the recursion fails, return the default, always valid `(0, None)`
284
    ///         Self::try_size_hint(depth).unwrap_or_default()
285
    ///     }
286
    ///
287
    ///     fn try_size_hint(depth: usize) -> Result<(usize, Option<usize>), MaxRecursionReached> {
288
    ///         // Protect against potential infinite recursion with
289
    ///         // `try_recursion_guard`.
290
    ///         size_hint::try_recursion_guard(depth, |depth| {
291
    ///             // If we aren't too deep, then `recursion_guard` calls
292
    ///             // this closure, which implements the natural size hint.
293
    ///             // Don't forget to use the new `depth` in all nested
294
    ///             // `try_size_hint` calls! We recommend shadowing the
295
    ///             // parameter, like what is done here, so that you can't
296
    ///             // accidentally use the wrong depth.
297
    ///             Ok(size_hint::and(
298
    ///                 <A as Arbitrary>::try_size_hint(depth)?,
299
    ///                 <B as Arbitrary>::try_size_hint(depth)?,
300
    ///             ))
301
    ///         })
302
    ///     }
303
    /// }
304
    /// ```
305
    ///
306
    /// ## Invariant
307
    ///
308
    /// It must be possible to construct every possible output using only inputs
309
    /// of lengths bounded by these parameters. This applies to both
310
    /// [`Arbitrary::arbitrary`] and [`Arbitrary::arbitrary_take_rest`].
311
    ///
312
    /// This is trivially true for `(0, None)`. To restrict this further, it
313
    /// must be proven that all inputs that are now excluded produced redundant
314
    /// outputs which are still possible to produce using the reduced input
315
    /// space.
316
    ///
317
    /// [iterator-size-hint]: https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html#method.size_hint
318
    /// [`try_size_hint`]: Arbitrary::try_size_hint
319
    #[inline]
320
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
321
0
        let _ = depth;
322
0
        (0, None)
323
0
    }
324
325
    /// Get a size hint for how many bytes out of an `Unstructured` this type
326
    /// needs to construct itself.
327
    ///
328
    /// Unlike [`size_hint`], this function keeps the information that the
329
    /// recursion limit was reached. This is required to "short circuit" the
330
    /// calculation and avoid exponential blowup with recursive structures.
331
    ///
332
    /// If you are implementing [`size_hint`] for a struct that could be
333
    /// recursive, you should implement `try_size_hint` and call the
334
    /// `try_size_hint` when recursing
335
    ///
336
    ///
337
    /// The return value is similar to [`core::iter::Iterator::size_hint`]: it
338
    /// returns a tuple where the first element is a lower bound on the number
339
    /// of bytes required, and the second element is an optional upper bound.
340
    ///
341
    /// The default implementation returns the value of [`size_hint`] which is
342
    /// correct for any type, but might lead to exponential blowup when dealing
343
    /// with recursive types.
344
    ///
345
    /// ## Invariant
346
    ///
347
    /// It must be possible to construct every possible output using only inputs
348
    /// of lengths bounded by these parameters. This applies to both
349
    /// [`Arbitrary::arbitrary`] and [`Arbitrary::arbitrary_take_rest`].
350
    ///
351
    /// This is trivially true for `(0, None)`. To restrict this further, it
352
    /// must be proven that all inputs that are now excluded produced redundant
353
    /// outputs which are still possible to produce using the reduced input
354
    /// space.
355
    ///
356
    /// ## When to implement `try_size_hint`
357
    ///
358
    /// If you 100% know that the type you are implementing `Arbitrary` for is
359
    /// not a recursive type, or your implementation is not transitively calling
360
    /// any other `size_hint` methods, you may implement [`size_hint`], and the
361
    /// default `try_size_hint` implementation will use it.
362
    ///
363
    /// Note that if you are implementing `Arbitrary` for a generic type, you
364
    /// cannot guarantee the lack of type recursion!
365
    ///
366
    /// Otherwise, when there is possible type recursion, you should implement
367
    /// `try_size_hint` instead.
368
    ///
369
    /// ## The `depth` parameter
370
    ///
371
    /// When implementing `try_size_hint`, you need to use
372
    /// [`arbitrary::size_hint::try_recursion_guard(depth)`][crate::size_hint::try_recursion_guard]
373
    /// to prevent potential infinite recursion when calculating size hints for
374
    /// potentially recursive types:
375
    ///
376
    /// ```
377
    /// use arbitrary::{size_hint, Arbitrary, MaxRecursionReached, Unstructured};
378
    ///
379
    /// // This can potentially be a recursive type if `L` or `R` contain
380
    /// // something like `Box<Option<MyEither<L, R>>>`!
381
    /// enum MyEither<L, R> {
382
    ///     Left(L),
383
    ///     Right(R),
384
    /// }
385
    ///
386
    /// impl<'a, L, R> Arbitrary<'a> for MyEither<L, R>
387
    /// where
388
    ///     L: Arbitrary<'a>,
389
    ///     R: Arbitrary<'a>,
390
    /// {
391
    ///     fn arbitrary(u: &mut Unstructured) -> arbitrary::Result<Self> {
392
    ///         // ...
393
    /// #       unimplemented!()
394
    ///     }
395
    ///
396
    ///     fn size_hint(depth: usize) -> (usize, Option<usize>) {
397
    ///         // Return the value of `try_size_hint`
398
    ///         //
399
    ///         // If the recursion fails, return the default `(0, None)` range,
400
    ///         // which is always valid.
401
    ///         Self::try_size_hint(depth).unwrap_or_default()
402
    ///     }
403
    ///
404
    ///     fn try_size_hint(depth: usize) -> Result<(usize, Option<usize>), MaxRecursionReached> {
405
    ///         // Protect against potential infinite recursion with
406
    ///         // `try_recursion_guard`.
407
    ///         size_hint::try_recursion_guard(depth, |depth| {
408
    ///             // If we aren't too deep, then `recursion_guard` calls
409
    ///             // this closure, which implements the natural size hint.
410
    ///             // Don't forget to use the new `depth` in all nested
411
    ///             // `try_size_hint` calls! We recommend shadowing the
412
    ///             // parameter, like what is done here, so that you can't
413
    ///             // accidentally use the wrong depth.
414
    ///             Ok(size_hint::or(
415
    ///                 <L as Arbitrary>::try_size_hint(depth)?,
416
    ///                 <R as Arbitrary>::try_size_hint(depth)?,
417
    ///             ))
418
    ///         })
419
    ///     }
420
    /// }
421
    /// ```
422
    #[inline]
423
0
    fn try_size_hint(depth: usize) -> Result<(usize, Option<usize>), MaxRecursionReached> {
424
0
        Ok(Self::size_hint(depth))
425
0
    }
426
}
427
428
/// Multiple conflicting arbitrary attributes are used on the same field:
429
/// ```compile_fail
430
/// #[derive(::arbitrary::Arbitrary)]
431
/// struct Point {
432
///     #[arbitrary(value = 2)]
433
///     #[arbitrary(value = 2)]
434
///     x: i32,
435
/// }
436
/// ```
437
///
438
/// An unknown attribute:
439
/// ```compile_fail
440
/// #[derive(::arbitrary::Arbitrary)]
441
/// struct Point {
442
///     #[arbitrary(unknown_attr)]
443
///     x: i32,
444
/// }
445
/// ```
446
///
447
/// An unknown attribute with a value:
448
/// ```compile_fail
449
/// #[derive(::arbitrary::Arbitrary)]
450
/// struct Point {
451
///     #[arbitrary(unknown_attr = 13)]
452
///     x: i32,
453
/// }
454
/// ```
455
///
456
/// `value` without RHS:
457
/// ```compile_fail
458
/// #[derive(::arbitrary::Arbitrary)]
459
/// struct Point {
460
///     #[arbitrary(value)]
461
///     x: i32,
462
/// }
463
/// ```
464
///
465
/// `with` without RHS:
466
/// ```compile_fail
467
/// #[derive(::arbitrary::Arbitrary)]
468
/// struct Point {
469
///     #[arbitrary(with)]
470
///     x: i32,
471
/// }
472
/// ```
473
///
474
/// Multiple conflicting bounds at the container-level:
475
/// ```compile_fail
476
/// #[derive(::arbitrary::Arbitrary)]
477
/// #[arbitrary(bound = "T: Default")]
478
/// #[arbitrary(bound = "T: Default")]
479
/// struct Point<T: Default> {
480
///     #[arbitrary(default)]
481
///     x: T,
482
/// }
483
/// ```
484
///
485
/// Multiple conflicting bounds in a single bound attribute:
486
/// ```compile_fail
487
/// #[derive(::arbitrary::Arbitrary)]
488
/// #[arbitrary(bound = "T: Default, T: Default")]
489
/// struct Point<T: Default> {
490
///     #[arbitrary(default)]
491
///     x: T,
492
/// }
493
/// ```
494
///
495
/// Multiple conflicting bounds in multiple bound attributes:
496
/// ```compile_fail
497
/// #[derive(::arbitrary::Arbitrary)]
498
/// #[arbitrary(bound = "T: Default", bound = "T: Default")]
499
/// struct Point<T: Default> {
500
///     #[arbitrary(default)]
501
///     x: T,
502
/// }
503
/// ```
504
///
505
/// Too many bounds supplied:
506
/// ```compile_fail
507
/// #[derive(::arbitrary::Arbitrary)]
508
/// #[arbitrary(bound = "T: Default")]
509
/// struct Point {
510
///     x: i32,
511
/// }
512
/// ```
513
///
514
/// Too many bounds supplied across multiple attributes:
515
/// ```compile_fail
516
/// #[derive(::arbitrary::Arbitrary)]
517
/// #[arbitrary(bound = "T: Default")]
518
/// #[arbitrary(bound = "U: Default")]
519
/// struct Point<T: Default> {
520
///     #[arbitrary(default)]
521
///     x: T,
522
/// }
523
/// ```
524
///
525
/// Attempt to use the derive attribute on an enum variant:
526
/// ```compile_fail
527
/// #[derive(::arbitrary::Arbitrary)]
528
/// enum Enum<T: Default> {
529
///     #[arbitrary(default)]
530
///     Variant(T),
531
/// }
532
/// ```
533
#[cfg(all(doctest, feature = "derive"))]
534
pub struct CompileFailTests;