arbitrary/unstructured.rs
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//! Wrappers around raw, unstructured bytes.
10
11use crate::{Arbitrary, Error, Result};
12use std::marker::PhantomData;
13use std::{mem, ops};
14
15/// A source of unstructured data.
16///
17/// An `Unstructured` helps `Arbitrary` implementations interpret raw data
18/// (typically provided by a fuzzer) as a "DNA string" that describes how to
19/// construct the `Arbitrary` type. The goal is that a small change to the "DNA
20/// string" (the raw data wrapped by an `Unstructured`) results in a small
21/// change to the generated `Arbitrary` instance. This helps a fuzzer
22/// efficiently explore the `Arbitrary`'s input space.
23///
24/// `Unstructured` is deterministic: given the same raw data, the same series of
25/// API calls will return the same results (modulo system resource constraints,
26/// like running out of memory). However, `Unstructured` does not guarantee
27/// anything beyond that: it makes not guarantee that it will yield bytes from
28/// the underlying data in any particular order.
29///
30/// You shouldn't generally need to use an `Unstructured` unless you are writing
31/// a custom `Arbitrary` implementation by hand, instead of deriving it. Mostly,
32/// you should just be passing it through to nested `Arbitrary::arbitrary`
33/// calls.
34///
35/// # Example
36///
37/// Imagine you were writing a color conversion crate. You might want to write
38/// fuzz tests that take a random RGB color and assert various properties, run
39/// functions and make sure nothing panics, etc.
40///
41/// Below is what translating the fuzzer's raw input into an `Unstructured` and
42/// using that to generate an arbitrary RGB color might look like:
43///
44/// ```
45/// # #[cfg(feature = "derive")] fn foo() {
46/// use arbitrary::{Arbitrary, Unstructured};
47///
48/// /// An RGB color.
49/// #[derive(Arbitrary)]
50/// pub struct Rgb {
51/// r: u8,
52/// g: u8,
53/// b: u8,
54/// }
55///
56/// // Get the raw bytes from the fuzzer.
57/// # let get_input_from_fuzzer = || &[];
58/// let raw_data: &[u8] = get_input_from_fuzzer();
59///
60/// // Wrap it in an `Unstructured`.
61/// let mut unstructured = Unstructured::new(raw_data);
62///
63/// // Generate an `Rgb` color and run our checks.
64/// if let Ok(rgb) = Rgb::arbitrary(&mut unstructured) {
65/// # let run_my_color_conversion_checks = |_| {};
66/// run_my_color_conversion_checks(rgb);
67/// }
68/// # }
69/// ```
70pub struct Unstructured<'a> {
71 data: &'a [u8],
72}
73
74impl<'a> Unstructured<'a> {
75 /// Create a new `Unstructured` from the given raw data.
76 ///
77 /// # Example
78 ///
79 /// ```
80 /// use arbitrary::Unstructured;
81 ///
82 /// let u = Unstructured::new(&[1, 2, 3, 4]);
83 /// ```
84 pub fn new(data: &'a [u8]) -> Self {
85 Unstructured { data }
86 }
87
88 /// Get the number of remaining bytes of underlying data that are still
89 /// available.
90 ///
91 /// # Example
92 ///
93 /// ```
94 /// use arbitrary::{Arbitrary, Unstructured};
95 ///
96 /// let mut u = Unstructured::new(&[1, 2, 3]);
97 ///
98 /// // Initially have three bytes of data.
99 /// assert_eq!(u.len(), 3);
100 ///
101 /// // Generating a `bool` consumes one byte from the underlying data, so
102 /// // we are left with two bytes afterwards.
103 /// let _ = bool::arbitrary(&mut u);
104 /// assert_eq!(u.len(), 2);
105 /// ```
106 #[inline]
107 pub fn len(&self) -> usize {
108 self.data.len()
109 }
110
111 /// Is the underlying unstructured data exhausted?
112 ///
113 /// `unstructured.is_empty()` is the same as `unstructured.len() == 0`.
114 ///
115 /// # Example
116 ///
117 /// ```
118 /// use arbitrary::{Arbitrary, Unstructured};
119 ///
120 /// let mut u = Unstructured::new(&[1, 2, 3, 4]);
121 ///
122 /// // Initially, we are not empty.
123 /// assert!(!u.is_empty());
124 ///
125 /// // Generating a `u32` consumes all four bytes of the underlying data, so
126 /// // we become empty afterwards.
127 /// let _ = u32::arbitrary(&mut u);
128 /// assert!(u.is_empty());
129 /// ```
130 #[inline]
131 pub fn is_empty(&self) -> bool {
132 self.len() == 0
133 }
134
135 /// Generate an arbitrary instance of `A`.
136 ///
137 /// This is simply a helper method that is equivalent to `<A as
138 /// Arbitrary>::arbitrary(self)`. This helper is a little bit more concise,
139 /// and can be used in situations where Rust's type inference will figure
140 /// out what `A` should be.
141 ///
142 /// # Example
143 ///
144 /// ```
145 /// # #[cfg(feature="derive")] fn foo() -> arbitrary::Result<()> {
146 /// use arbitrary::{Arbitrary, Unstructured};
147 ///
148 /// #[derive(Arbitrary)]
149 /// struct MyType {
150 /// // ...
151 /// }
152 ///
153 /// fn do_stuff(value: MyType) {
154 /// # let _ = value;
155 /// // ...
156 /// }
157 ///
158 /// let mut u = Unstructured::new(&[1, 2, 3, 4]);
159 ///
160 /// // Rust's type inference can figure out that `value` should be of type
161 /// // `MyType` here:
162 /// let value = u.arbitrary()?;
163 /// do_stuff(value);
164 /// # Ok(()) }
165 /// ```
166 pub fn arbitrary<A>(&mut self) -> Result<A>
167 where
168 A: Arbitrary<'a>,
169 {
170 <A as Arbitrary<'a>>::arbitrary(self)
171 }
172
173 /// Get the number of elements to insert when building up a collection of
174 /// arbitrary `ElementType`s.
175 ///
176 /// This uses the [`<ElementType as
177 /// Arbitrary>::size_hint`][crate::Arbitrary::size_hint] method to smartly
178 /// choose a length such that we most likely have enough underlying bytes to
179 /// construct that many arbitrary `ElementType`s.
180 ///
181 /// This should only be called within an `Arbitrary` implementation.
182 ///
183 /// # Example
184 ///
185 /// ```
186 /// use arbitrary::{Arbitrary, Result, Unstructured};
187 /// # pub struct MyCollection<T> { _t: std::marker::PhantomData<T> }
188 /// # impl<T> MyCollection<T> {
189 /// # pub fn with_capacity(capacity: usize) -> Self { MyCollection { _t: std::marker::PhantomData } }
190 /// # pub fn insert(&mut self, element: T) {}
191 /// # }
192 ///
193 /// impl<'a, T> Arbitrary<'a> for MyCollection<T>
194 /// where
195 /// T: Arbitrary<'a>,
196 /// {
197 /// fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
198 /// // Get the number of `T`s we should insert into our collection.
199 /// let len = u.arbitrary_len::<T>()?;
200 ///
201 /// // And then create a collection of that length!
202 /// let mut my_collection = MyCollection::with_capacity(len);
203 /// for _ in 0..len {
204 /// let element = T::arbitrary(u)?;
205 /// my_collection.insert(element);
206 /// }
207 ///
208 /// Ok(my_collection)
209 /// }
210 /// }
211 /// ```
212 pub fn arbitrary_len<ElementType>(&mut self) -> Result<usize>
213 where
214 ElementType: Arbitrary<'a>,
215 {
216 let byte_size = self.arbitrary_byte_size()?;
217 let (lower, upper) = <ElementType as Arbitrary>::size_hint(0);
218 let elem_size = upper.unwrap_or_else(|| lower * 2);
219 let elem_size = std::cmp::max(1, elem_size);
220 Ok(byte_size / elem_size)
221 }
222
223 fn arbitrary_byte_size(&mut self) -> Result<usize> {
224 if self.data.is_empty() {
225 Ok(0)
226 } else if self.data.len() == 1 {
227 self.data = &[];
228 Ok(0)
229 } else {
230 // Take lengths from the end of the data, since the `libFuzzer` folks
231 // found that this lets fuzzers more efficiently explore the input
232 // space.
233 //
234 // https://github.com/rust-fuzz/libfuzzer-sys/blob/0c450753/libfuzzer/utils/FuzzedDataProvider.h#L92-L97
235
236 // We only consume as many bytes as necessary to cover the entire
237 // range of the byte string.
238 let len = if self.data.len() <= std::u8::MAX as usize + 1 {
239 let bytes = 1;
240 let max_size = self.data.len() - bytes;
241 let (rest, for_size) = self.data.split_at(max_size);
242 self.data = rest;
243 Self::int_in_range_impl(0..=max_size as u8, for_size.iter().copied())?.0 as usize
244 } else if self.data.len() <= std::u16::MAX as usize + 1 {
245 let bytes = 2;
246 let max_size = self.data.len() - bytes;
247 let (rest, for_size) = self.data.split_at(max_size);
248 self.data = rest;
249 Self::int_in_range_impl(0..=max_size as u16, for_size.iter().copied())?.0 as usize
250 } else if self.data.len() <= std::u32::MAX as usize + 1 {
251 let bytes = 4;
252 let max_size = self.data.len() - bytes;
253 let (rest, for_size) = self.data.split_at(max_size);
254 self.data = rest;
255 Self::int_in_range_impl(0..=max_size as u32, for_size.iter().copied())?.0 as usize
256 } else {
257 let bytes = 8;
258 let max_size = self.data.len() - bytes;
259 let (rest, for_size) = self.data.split_at(max_size);
260 self.data = rest;
261 Self::int_in_range_impl(0..=max_size as u64, for_size.iter().copied())?.0 as usize
262 };
263
264 Ok(len)
265 }
266 }
267
268 /// Generate an integer within the given range.
269 ///
270 /// Do not use this to generate the size of a collection. Use
271 /// `arbitrary_len` instead.
272 ///
273 /// # Panics
274 ///
275 /// Panics if `range.start >= range.end`. That is, the given range must be
276 /// non-empty.
277 ///
278 /// # Example
279 ///
280 /// ```
281 /// use arbitrary::{Arbitrary, Unstructured};
282 ///
283 /// let mut u = Unstructured::new(&[1, 2, 3, 4]);
284 ///
285 /// let x: i32 = u.int_in_range(-5_000..=-1_000)
286 /// .expect("constructed `u` with enough bytes to generate an `i32`");
287 ///
288 /// assert!(-5_000 <= x);
289 /// assert!(x <= -1_000);
290 /// ```
291 pub fn int_in_range<T>(&mut self, range: ops::RangeInclusive<T>) -> Result<T>
292 where
293 T: Int,
294 {
295 let (result, bytes_consumed) = Self::int_in_range_impl(range, self.data.iter().cloned())?;
296 self.data = &self.data[bytes_consumed..];
297 Ok(result)
298 }
299
300 fn int_in_range_impl<T>(
301 range: ops::RangeInclusive<T>,
302 mut bytes: impl Iterator<Item = u8>,
303 ) -> Result<(T, usize)>
304 where
305 T: Int,
306 {
307 let start = range.start();
308 let end = range.end();
309 assert!(
310 start <= end,
311 "`arbitrary::Unstructured::int_in_range` requires a non-empty range"
312 );
313
314 // When there is only one possible choice, don't waste any entropy from
315 // the underlying data.
316 if start == end {
317 return Ok((*start, 0));
318 }
319
320 let range: T::Widest = end.as_widest() - start.as_widest();
321 let mut result = T::Widest::ZERO;
322 let mut offset: usize = 0;
323
324 while offset < mem::size_of::<T>()
325 && (range >> T::Widest::from_usize(offset * 8)) > T::Widest::ZERO
326 {
327 let byte = bytes.next().ok_or(Error::NotEnoughData)?;
328 result = (result << 8) | T::Widest::from_u8(byte);
329 offset += 1;
330 }
331
332 // Avoid division by zero.
333 if let Some(range) = range.checked_add(T::Widest::ONE) {
334 result = result % range;
335 }
336
337 Ok((
338 T::from_widest(start.as_widest().wrapping_add(result)),
339 offset,
340 ))
341 }
342
343 /// Choose one of the given choices.
344 ///
345 /// This should only be used inside of `Arbitrary` implementations.
346 ///
347 /// Returns an error if there is not enough underlying data to make a
348 /// choice or if no choices are provided.
349 ///
350 /// # Examples
351 ///
352 /// Selecting from an array of choices:
353 ///
354 /// ```
355 /// use arbitrary::Unstructured;
356 ///
357 /// let mut u = Unstructured::new(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]);
358 /// let choices = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];
359 ///
360 /// let choice = u.choose(&choices).unwrap();
361 ///
362 /// println!("chose {}", choice);
363 /// ```
364 ///
365 /// An error is returned if no choices are provided:
366 ///
367 /// ```
368 /// use arbitrary::Unstructured;
369 ///
370 /// let mut u = Unstructured::new(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]);
371 /// let choices: [char; 0] = [];
372 ///
373 /// let result = u.choose(&choices);
374 ///
375 /// assert!(result.is_err());
376 /// ```
377 pub fn choose<'b, T>(&mut self, choices: &'b [T]) -> Result<&'b T> {
378 if choices.is_empty() {
379 return Err(Error::EmptyChoose);
380 }
381 let idx = self.int_in_range(0..=choices.len() - 1)?;
382 Ok(&choices[idx])
383 }
384
385 /// Fill a `buffer` with bytes from the underlying raw data.
386 ///
387 /// This should only be called within an `Arbitrary` implementation. This is
388 /// a very low-level operation. You should generally prefer calling nested
389 /// `Arbitrary` implementations like `<Vec<u8>>::arbitrary` and
390 /// `String::arbitrary` over using this method directly.
391 ///
392 /// If this `Unstructured` does not have enough underlying data to fill the
393 /// whole `buffer`, it pads the buffer out with zeros.
394 ///
395 /// # Example
396 ///
397 /// ```
398 /// use arbitrary::Unstructured;
399 ///
400 /// let mut u = Unstructured::new(&[1, 2, 3, 4]);
401 ///
402 /// let mut buf = [0; 2];
403 ///
404 /// assert!(u.fill_buffer(&mut buf).is_ok());
405 /// assert_eq!(buf, [1, 2]);
406 ///
407 /// assert!(u.fill_buffer(&mut buf).is_ok());
408 /// assert_eq!(buf, [3, 4]);
409 ///
410 /// assert!(u.fill_buffer(&mut buf).is_ok());
411 /// assert_eq!(buf, [0, 0]);
412 /// ```
413 pub fn fill_buffer(&mut self, buffer: &mut [u8]) -> Result<()> {
414 let n = std::cmp::min(buffer.len(), self.data.len());
415 buffer[..n].copy_from_slice(&self.data[..n]);
416 for byte in buffer[n..].iter_mut() {
417 *byte = 0;
418 }
419 self.data = &self.data[n..];
420 Ok(())
421 }
422
423 /// Provide `size` bytes from the underlying raw data.
424 ///
425 /// This should only be called within an `Arbitrary` implementation. This is
426 /// a very low-level operation. You should generally prefer calling nested
427 /// `Arbitrary` implementations like `<Vec<u8>>::arbitrary` and
428 /// `String::arbitrary` over using this method directly.
429 ///
430 /// # Example
431 ///
432 /// ```
433 /// use arbitrary::Unstructured;
434 ///
435 /// let mut u = Unstructured::new(&[1, 2, 3, 4]);
436 ///
437 /// assert!(u.bytes(2).unwrap() == &[1, 2]);
438 /// assert!(u.bytes(2).unwrap() == &[3, 4]);
439 /// ```
440 pub fn bytes(&mut self, size: usize) -> Result<&'a [u8]> {
441 if self.data.len() < size {
442 return Err(Error::NotEnoughData);
443 }
444
445 let (for_buf, rest) = self.data.split_at(size);
446 self.data = rest;
447 Ok(for_buf)
448 }
449
450 /// Peek at `size` number of bytes of the underlying raw input.
451 ///
452 /// Does not consume the bytes, only peeks at them.
453 ///
454 /// Returns `None` if there are not `size` bytes left in the underlying raw
455 /// input.
456 ///
457 /// # Example
458 ///
459 /// ```
460 /// use arbitrary::Unstructured;
461 ///
462 /// let u = Unstructured::new(&[1, 2, 3]);
463 ///
464 /// assert_eq!(u.peek_bytes(0).unwrap(), []);
465 /// assert_eq!(u.peek_bytes(1).unwrap(), [1]);
466 /// assert_eq!(u.peek_bytes(2).unwrap(), [1, 2]);
467 /// assert_eq!(u.peek_bytes(3).unwrap(), [1, 2, 3]);
468 ///
469 /// assert!(u.peek_bytes(4).is_none());
470 /// ```
471 pub fn peek_bytes(&self, size: usize) -> Option<&'a [u8]> {
472 self.data.get(..size)
473 }
474
475 /// Consume all of the rest of the remaining underlying bytes.
476 ///
477 /// Returns a slice of all the remaining, unconsumed bytes.
478 ///
479 /// # Example
480 ///
481 /// ```
482 /// use arbitrary::Unstructured;
483 ///
484 /// let mut u = Unstructured::new(&[1, 2, 3]);
485 ///
486 /// let mut remaining = u.take_rest();
487 ///
488 /// assert_eq!(remaining, [1, 2, 3]);
489 /// ```
490 pub fn take_rest(mut self) -> &'a [u8] {
491 mem::replace(&mut self.data, &[])
492 }
493
494 /// Provide an iterator over elements for constructing a collection
495 ///
496 /// This is useful for implementing [`Arbitrary::arbitrary`] on collections
497 /// since the implementation is simply `u.arbitrary_iter()?.collect()`
498 pub fn arbitrary_iter<'b, ElementType: Arbitrary<'a>>(
499 &'b mut self,
500 ) -> Result<ArbitraryIter<'a, 'b, ElementType>> {
501 Ok(ArbitraryIter {
502 u: &mut *self,
503 _marker: PhantomData,
504 })
505 }
506
507 /// Provide an iterator over elements for constructing a collection from
508 /// all the remaining bytes.
509 ///
510 /// This is useful for implementing [`Arbitrary::arbitrary_take_rest`] on collections
511 /// since the implementation is simply `u.arbitrary_take_rest_iter()?.collect()`
512 pub fn arbitrary_take_rest_iter<ElementType: Arbitrary<'a>>(
513 self,
514 ) -> Result<ArbitraryTakeRestIter<'a, ElementType>> {
515 let (lower, upper) = ElementType::size_hint(0);
516
517 let elem_size = upper.unwrap_or(lower * 2);
518 let elem_size = std::cmp::max(1, elem_size);
519 let size = self.len() / elem_size;
520 Ok(ArbitraryTakeRestIter {
521 size,
522 u: Some(self),
523 _marker: PhantomData,
524 })
525 }
526}
527
528/// Utility iterator produced by [`Unstructured::arbitrary_iter`]
529pub struct ArbitraryIter<'a, 'b, ElementType> {
530 u: &'b mut Unstructured<'a>,
531 _marker: PhantomData<ElementType>,
532}
533
534impl<'a, 'b, ElementType: Arbitrary<'a>> Iterator for ArbitraryIter<'a, 'b, ElementType> {
535 type Item = Result<ElementType>;
536 fn next(&mut self) -> Option<Result<ElementType>> {
537 let keep_going = self.u.arbitrary().unwrap_or(false);
538 if keep_going {
539 Some(Arbitrary::arbitrary(self.u))
540 } else {
541 None
542 }
543 }
544}
545
546/// Utility iterator produced by [`Unstructured::arbitrary_take_rest_iter`]
547pub struct ArbitraryTakeRestIter<'a, ElementType> {
548 u: Option<Unstructured<'a>>,
549 size: usize,
550 _marker: PhantomData<ElementType>,
551}
552
553impl<'a, ElementType: Arbitrary<'a>> Iterator for ArbitraryTakeRestIter<'a, ElementType> {
554 type Item = Result<ElementType>;
555 fn next(&mut self) -> Option<Result<ElementType>> {
556 if let Some(mut u) = self.u.take() {
557 if self.size == 1 {
558 Some(Arbitrary::arbitrary_take_rest(u))
559 } else if self.size == 0 {
560 None
561 } else {
562 self.size -= 1;
563 let ret = Arbitrary::arbitrary(&mut u);
564 self.u = Some(u);
565 Some(ret)
566 }
567 } else {
568 None
569 }
570 }
571}
572
573/// A trait that is implemented for all of the primitive integers:
574///
575/// * `u8`
576/// * `u16`
577/// * `u32`
578/// * `u64`
579/// * `u128`
580/// * `usize`
581/// * `i8`
582/// * `i16`
583/// * `i32`
584/// * `i64`
585/// * `i128`
586/// * `isize`
587///
588/// Don't implement this trait yourself.
589pub trait Int:
590 Copy
591 + PartialOrd
592 + Ord
593 + ops::Sub<Self, Output = Self>
594 + ops::Rem<Self, Output = Self>
595 + ops::Shr<Self, Output = Self>
596 + ops::Shl<usize, Output = Self>
597 + ops::BitOr<Self, Output = Self>
598{
599 #[doc(hidden)]
600 type Widest: Int;
601
602 #[doc(hidden)]
603 const ZERO: Self;
604
605 #[doc(hidden)]
606 const ONE: Self;
607
608 #[doc(hidden)]
609 fn as_widest(self) -> Self::Widest;
610
611 #[doc(hidden)]
612 fn from_widest(w: Self::Widest) -> Self;
613
614 #[doc(hidden)]
615 fn from_u8(b: u8) -> Self;
616
617 #[doc(hidden)]
618 fn from_usize(u: usize) -> Self;
619
620 #[doc(hidden)]
621 fn checked_add(self, rhs: Self) -> Option<Self>;
622
623 #[doc(hidden)]
624 fn wrapping_add(self, rhs: Self) -> Self;
625}
626
627macro_rules! impl_int {
628 ( $( $ty:ty : $widest:ty ; )* ) => {
629 $(
630 impl Int for $ty {
631 type Widest = $widest;
632
633 const ZERO: Self = 0;
634
635 const ONE: Self = 1;
636
637 fn as_widest(self) -> Self::Widest {
638 self as $widest
639 }
640
641 fn from_widest(w: Self::Widest) -> Self {
642 let x = <$ty>::max_value().as_widest();
643 (w % x) as Self
644 }
645
646 fn from_u8(b: u8) -> Self {
647 b as Self
648 }
649
650 fn from_usize(u: usize) -> Self {
651 u as Self
652 }
653
654 fn checked_add(self, rhs: Self) -> Option<Self> {
655 <$ty>::checked_add(self, rhs)
656 }
657
658 fn wrapping_add(self, rhs: Self) -> Self {
659 <$ty>::wrapping_add(self, rhs)
660 }
661 }
662 )*
663 }
664}
665
666impl_int! {
667 u8: u128;
668 u16: u128;
669 u32: u128;
670 u64: u128;
671 u128: u128;
672 usize: u128;
673 i8: i128;
674 i16: i128;
675 i32: i128;
676 i64: i128;
677 i128: i128;
678 isize: i128;
679}
680
681#[cfg(test)]
682mod tests {
683 use super::*;
684
685 #[test]
686 fn test_byte_size() {
687 let mut u = Unstructured::new(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 6]);
688 // Should take one byte off the end
689 assert_eq!(u.arbitrary_byte_size().unwrap(), 6);
690 assert_eq!(u.len(), 9);
691 let mut v = vec![];
692 v.resize(260, 0);
693 v.push(1);
694 v.push(4);
695 let mut u = Unstructured::new(&v);
696 // Should read two bytes off the end
697 assert_eq!(u.arbitrary_byte_size().unwrap(), 0x104);
698 assert_eq!(u.len(), 260);
699 }
700
701 #[test]
702 fn int_in_range_of_one() {
703 let mut u = Unstructured::new(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 6]);
704 let x = u.int_in_range(0..=0).unwrap();
705 assert_eq!(x, 0);
706 let choice = *u.choose(&[42]).unwrap();
707 assert_eq!(choice, 42)
708 }
709
710 #[test]
711 fn int_in_range_uses_minimal_amount_of_bytes() {
712 let mut u = Unstructured::new(&[1]);
713 u.int_in_range::<u8>(0..=u8::MAX).unwrap();
714
715 let mut u = Unstructured::new(&[1]);
716 u.int_in_range::<u32>(0..=u8::MAX as u32).unwrap();
717
718 let mut u = Unstructured::new(&[1]);
719 u.int_in_range::<u32>(0..=u8::MAX as u32 + 1).unwrap_err();
720 }
721}