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::{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 /// ``` 70 pub struct Unstructured<'a> { 71 data: &'a [u8], 72 } 73 74 impl<'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 /// ``` new(data: &'a [u8]) -> Self84 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] len(&self) -> usize107 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] is_empty(&self) -> bool131 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 /// ``` arbitrary<A>(&mut self) -> Result<A> where A: Arbitrary<'a>,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 /// ``` arbitrary_len<ElementType>(&mut self) -> Result<usize> where ElementType: Arbitrary<'a>,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 arbitrary_byte_size(&mut self) -> Result<usize>223 fn arbitrary_byte_size(&mut self) -> Result<usize> { 224 if self.data.len() == 0 { 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 /// ``` int_in_range<T>(&mut self, range: ops::RangeInclusive<T>) -> Result<T> where T: Int,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 int_in_range_impl<T>( range: ops::RangeInclusive<T>, mut bytes: impl Iterator<Item = u8>, ) -> Result<(T, usize)> where T: Int,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)) > 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 /// ``` choose<'b, T>(&mut self, choices: &'b [T]) -> Result<&'b T>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 data to fill the whole 393 /// `buffer`, an error is returned. 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 /// assert!(u.fill_buffer(&mut buf).is_ok()); 404 /// assert!(u.fill_buffer(&mut buf).is_ok()); 405 /// ``` fill_buffer(&mut self, buffer: &mut [u8]) -> Result<()>406 pub fn fill_buffer(&mut self, buffer: &mut [u8]) -> Result<()> { 407 let n = std::cmp::min(buffer.len(), self.data.len()); 408 for i in 0..n { 409 buffer[i] = self.data[i]; 410 } 411 for i in self.data.len()..buffer.len() { 412 buffer[i] = 0; 413 } 414 self.data = &self.data[n..]; 415 Ok(()) 416 } 417 418 /// Provide `size` bytes from the underlying raw data. 419 /// 420 /// This should only be called within an `Arbitrary` implementation. This is 421 /// a very low-level operation. You should generally prefer calling nested 422 /// `Arbitrary` implementations like `<Vec<u8>>::arbitrary` and 423 /// `String::arbitrary` over using this method directly. 424 /// 425 /// # Example 426 /// 427 /// ``` 428 /// use arbitrary::Unstructured; 429 /// 430 /// let mut u = Unstructured::new(&[1, 2, 3, 4]); 431 /// 432 /// assert!(u.bytes(2).unwrap() == &[1, 2]); 433 /// assert!(u.bytes(2).unwrap() == &[3, 4]); 434 /// ``` bytes(&mut self, size: usize) -> Result<&'a [u8]>435 pub fn bytes(&mut self, size: usize) -> Result<&'a [u8]> { 436 if self.data.len() < size { 437 return Err(Error::NotEnoughData); 438 } 439 440 let (for_buf, rest) = self.data.split_at(size); 441 self.data = rest; 442 Ok(for_buf) 443 } 444 445 /// Peek at `size` number of bytes of the underlying raw input. 446 /// 447 /// Does not consume the bytes, only peeks at them. 448 /// 449 /// Returns `None` if there are not `size` bytes left in the underlying raw 450 /// input. 451 /// 452 /// # Example 453 /// 454 /// ``` 455 /// use arbitrary::Unstructured; 456 /// 457 /// let u = Unstructured::new(&[1, 2, 3]); 458 /// 459 /// assert_eq!(u.peek_bytes(0).unwrap(), []); 460 /// assert_eq!(u.peek_bytes(1).unwrap(), [1]); 461 /// assert_eq!(u.peek_bytes(2).unwrap(), [1, 2]); 462 /// assert_eq!(u.peek_bytes(3).unwrap(), [1, 2, 3]); 463 /// 464 /// assert!(u.peek_bytes(4).is_none()); 465 /// ``` peek_bytes(&self, size: usize) -> Option<&'a [u8]>466 pub fn peek_bytes(&self, size: usize) -> Option<&'a [u8]> { 467 self.data.get(..size) 468 } 469 470 /// Consume all of the rest of the remaining underlying bytes. 471 /// 472 /// Returns a slice of all the remaining, unconsumed bytes. 473 /// 474 /// # Example 475 /// 476 /// ``` 477 /// use arbitrary::Unstructured; 478 /// 479 /// let mut u = Unstructured::new(&[1, 2, 3]); 480 /// 481 /// let mut remaining = u.take_rest(); 482 /// 483 /// assert_eq!(remaining, [1, 2, 3]); 484 /// ``` take_rest(mut self) -> &'a [u8]485 pub fn take_rest(mut self) -> &'a [u8] { 486 mem::replace(&mut self.data, &[]) 487 } 488 489 /// Provide an iterator over elements for constructing a collection 490 /// 491 /// This is useful for implementing [`Arbitrary::arbitrary`] on collections 492 /// since the implementation is simply `u.arbitrary_iter()?.collect()` arbitrary_iter<'b, ElementType: Arbitrary<'a>>( &'b mut self, ) -> Result<ArbitraryIter<'a, 'b, ElementType>>493 pub fn arbitrary_iter<'b, ElementType: Arbitrary<'a>>( 494 &'b mut self, 495 ) -> Result<ArbitraryIter<'a, 'b, ElementType>> { 496 Ok(ArbitraryIter { 497 u: &mut *self, 498 _marker: PhantomData, 499 }) 500 } 501 502 /// Provide an iterator over elements for constructing a collection from 503 /// all the remaining bytes. 504 /// 505 /// This is useful for implementing [`Arbitrary::arbitrary_take_rest`] on collections 506 /// since the implementation is simply `u.arbitrary_take_rest_iter()?.collect()` arbitrary_take_rest_iter<ElementType: Arbitrary<'a>>( self, ) -> Result<ArbitraryTakeRestIter<'a, ElementType>>507 pub fn arbitrary_take_rest_iter<ElementType: Arbitrary<'a>>( 508 self, 509 ) -> Result<ArbitraryTakeRestIter<'a, ElementType>> { 510 let (lower, upper) = ElementType::size_hint(0); 511 512 let elem_size = upper.unwrap_or(lower * 2); 513 let elem_size = std::cmp::max(1, elem_size); 514 let size = self.len() / elem_size; 515 Ok(ArbitraryTakeRestIter { 516 size, 517 u: Some(self), 518 _marker: PhantomData, 519 }) 520 } 521 } 522 523 /// Utility iterator produced by [`Unstructured::arbitrary_iter`] 524 pub struct ArbitraryIter<'a, 'b, ElementType> { 525 u: &'b mut Unstructured<'a>, 526 _marker: PhantomData<ElementType>, 527 } 528 529 impl<'a, 'b, ElementType: Arbitrary<'a>> Iterator for ArbitraryIter<'a, 'b, ElementType> { 530 type Item = Result<ElementType>; next(&mut self) -> Option<Result<ElementType>>531 fn next(&mut self) -> Option<Result<ElementType>> { 532 let keep_going = self.u.arbitrary().unwrap_or(false); 533 if keep_going { 534 Some(Arbitrary::arbitrary(self.u)) 535 } else { 536 None 537 } 538 } 539 } 540 541 /// Utility iterator produced by [`Unstructured::arbitrary_take_rest_iter`] 542 pub struct ArbitraryTakeRestIter<'a, ElementType> { 543 u: Option<Unstructured<'a>>, 544 size: usize, 545 _marker: PhantomData<ElementType>, 546 } 547 548 impl<'a, ElementType: Arbitrary<'a>> Iterator for ArbitraryTakeRestIter<'a, ElementType> { 549 type Item = Result<ElementType>; next(&mut self) -> Option<Result<ElementType>>550 fn next(&mut self) -> Option<Result<ElementType>> { 551 if let Some(mut u) = self.u.take() { 552 if self.size == 1 { 553 Some(Arbitrary::arbitrary_take_rest(u)) 554 } else if self.size == 0 { 555 None 556 } else { 557 self.size -= 1; 558 let ret = Arbitrary::arbitrary(&mut u); 559 self.u = Some(u); 560 Some(ret) 561 } 562 } else { 563 None 564 } 565 } 566 } 567 568 /// A trait that is implemented for all of the primitive integers: 569 /// 570 /// * `u8` 571 /// * `u16` 572 /// * `u32` 573 /// * `u64` 574 /// * `u128` 575 /// * `usize` 576 /// * `i8` 577 /// * `i16` 578 /// * `i32` 579 /// * `i64` 580 /// * `i128` 581 /// * `isize` 582 /// 583 /// Don't implement this trait yourself. 584 pub trait Int: 585 Copy 586 + PartialOrd 587 + Ord 588 + ops::Sub<Self, Output = Self> 589 + ops::Rem<Self, Output = Self> 590 + ops::Shr<Self, Output = Self> 591 + ops::Shl<usize, Output = Self> 592 + ops::BitOr<Self, Output = Self> 593 { 594 #[doc(hidden)] 595 type Widest: Int; 596 597 #[doc(hidden)] 598 const ZERO: Self; 599 600 #[doc(hidden)] 601 const ONE: Self; 602 603 #[doc(hidden)] as_widest(self) -> Self::Widest604 fn as_widest(self) -> Self::Widest; 605 606 #[doc(hidden)] from_widest(w: Self::Widest) -> Self607 fn from_widest(w: Self::Widest) -> Self; 608 609 #[doc(hidden)] from_u8(b: u8) -> Self610 fn from_u8(b: u8) -> Self; 611 612 #[doc(hidden)] from_usize(u: usize) -> Self613 fn from_usize(u: usize) -> Self; 614 615 #[doc(hidden)] checked_add(self, rhs: Self) -> Option<Self>616 fn checked_add(self, rhs: Self) -> Option<Self>; 617 618 #[doc(hidden)] wrapping_add(self, rhs: Self) -> Self619 fn wrapping_add(self, rhs: Self) -> Self; 620 } 621 622 macro_rules! impl_int { 623 ( $( $ty:ty : $widest:ty ; )* ) => { 624 $( 625 impl Int for $ty { 626 type Widest = $widest; 627 628 const ZERO: Self = 0; 629 630 const ONE: Self = 1; 631 632 fn as_widest(self) -> Self::Widest { 633 self as $widest 634 } 635 636 fn from_widest(w: Self::Widest) -> Self { 637 let x = <$ty>::max_value().as_widest(); 638 (w % x) as Self 639 } 640 641 fn from_u8(b: u8) -> Self { 642 b as Self 643 } 644 645 fn from_usize(u: usize) -> Self { 646 u as Self 647 } 648 649 fn checked_add(self, rhs: Self) -> Option<Self> { 650 <$ty>::checked_add(self, rhs) 651 } 652 653 fn wrapping_add(self, rhs: Self) -> Self { 654 <$ty>::wrapping_add(self, rhs) 655 } 656 } 657 )* 658 } 659 } 660 661 impl_int! { 662 u8: u128; 663 u16: u128; 664 u32: u128; 665 u64: u128; 666 u128: u128; 667 usize: u128; 668 i8: i128; 669 i16: i128; 670 i32: i128; 671 i64: i128; 672 i128: i128; 673 isize: i128; 674 } 675 676 #[cfg(test)] 677 mod tests { 678 use super::*; 679 680 #[test] test_byte_size()681 fn test_byte_size() { 682 let mut u = Unstructured::new(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 6]); 683 // Should take one byte off the end 684 assert_eq!(u.arbitrary_byte_size().unwrap(), 6); 685 assert_eq!(u.len(), 9); 686 let mut v = vec![]; 687 v.resize(260, 0); 688 v.push(1); 689 v.push(4); 690 let mut u = Unstructured::new(&v); 691 // Should read two bytes off the end 692 assert_eq!(u.arbitrary_byte_size().unwrap(), 0x104); 693 assert_eq!(u.len(), 260); 694 } 695 696 #[test] int_in_range_of_one()697 fn int_in_range_of_one() { 698 let mut u = Unstructured::new(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 6]); 699 let x = u.int_in_range(0..=0).unwrap(); 700 assert_eq!(x, 0); 701 let choice = *u.choose(&[42]).unwrap(); 702 assert_eq!(choice, 42) 703 } 704 } 705