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