reader.rs
1 //! Internal: Declare the Reader type for tor-bytes 2 3 use tor_error::{bad_api_usage, into_internal}; 4 5 use crate::{Error, Readable, Result}; 6 use std::num::NonZeroUsize; 7 8 /// A type for reading messages from a slice of bytes. 9 /// 10 /// Unlike io::Read, this object has a simpler error type, and is designed 11 /// for in-memory parsing only. 12 /// 13 /// The methods in [`Reader`] should never panic, with one exception: 14 /// the `extract` and `extract_n` methods will panic if the underlying 15 /// [`Readable`] object's `take_from` method panics. 16 /// 17 /// # Examples 18 /// 19 /// You can use a Reader to extract information byte-by-byte: 20 /// 21 /// ``` 22 /// use tor_bytes::{Reader,Result}; 23 /// let msg = [ 0x00, 0x01, 0x23, 0x45, 0x22, 0x00, 0x00, 0x00 ]; 24 /// let mut b = Reader::from_slice(&msg[..]); 25 /// // Multi-byte values are always big-endian. 26 /// assert_eq!(b.take_u32()?, 0x12345); 27 /// assert_eq!(b.take_u8()?, 0x22); 28 /// 29 /// // You can check on the length of the message... 30 /// assert_eq!(b.total_len(), 8); 31 /// assert_eq!(b.consumed(), 5); 32 /// assert_eq!(b.remaining(), 3); 33 /// // then skip over a some bytes... 34 /// b.advance(3)?; 35 /// // ... and check that the message is really exhausted. 36 /// b.should_be_exhausted()?; 37 /// # Result::Ok(()) 38 /// ``` 39 /// 40 /// You can also use a Reader to extract objects that implement Readable. 41 /// ``` 42 /// use tor_bytes::{Reader,Result,Readable}; 43 /// use std::net::Ipv4Addr; 44 /// let msg = [ 0x00, 0x04, 0x7f, 0x00, 0x00, 0x01]; 45 /// let mut b = Reader::from_slice(&msg[..]); 46 /// 47 /// let tp: u16 = b.extract()?; 48 /// let ip: Ipv4Addr = b.extract()?; 49 /// assert_eq!(tp, 4); 50 /// assert_eq!(ip, Ipv4Addr::LOCALHOST); 51 /// # Result::Ok(()) 52 /// ``` 53 pub struct Reader<'a> { 54 /// The underlying slice that we're reading from 55 b: &'a [u8], 56 /// The next position in the slice that we intend to read from. 57 off: usize, 58 /// What to do if we run out of data - IOW are we reading a possibly incomplete message 59 completeness: Completeness, 60 } 61 62 /// Whether we're supposed to have the complete message, or not 63 /// 64 /// IOW are we reading a possibly incomplete message? 65 /// 66 /// Affects the error return if we run out of data 67 /// ([`Reader::incomplete_error`]). 68 #[derive(Copy, Clone, Debug)] 69 enum Completeness { 70 /// We might not have the whole message, and that is expected 71 /// 72 /// Throw [`Error::Incomplete`] 73 PossiblyIncomplete, 74 /// We ought to have the whole message 75 /// 76 /// Throw [`Error::MissingData'] 77 SupposedlyComplete, 78 } 79 80 impl<'a> Reader<'a> { 81 /// Construct a new Reader from a slice of bytes. 82 /// 83 /// In tests, prefer [`Reader::from_slice_for_test`]. 84 pub fn from_slice(slice: &'a [u8]) -> Self { 85 Reader { 86 b: slice, 87 off: 0, 88 completeness: Completeness::SupposedlyComplete, 89 } 90 } 91 /// Construct a new Reader from a slice of bytes which may not be complete. 92 /// 93 /// This can be used to try to deserialise a message received from a protocol stream, 94 /// if we don't know how much data we needed to buffer. 95 /// 96 /// [`Readable`] methods, [`extract`](Reader::extract), and so on, 97 /// will return [`Error::Incomplete`] if the message is incomplete, 98 /// and reading more would help. 99 /// 100 /// (This is achieved via [`incomplete_error`](Reader::incomplete_error.) 101 /// 102 /// # Warning about denial of service through excessive memory use 103 /// 104 /// It is hazardous to use this approach unless the buffer size is limited, 105 /// since the sender could send an apparently-very-large message. 106 /// 107 /// # Warning about sub-readers 108 /// 109 /// If you are constructing other readers from data extracted from this one, 110 /// make sure to use [`Reader::from_slice`] instead of this method! 111 /// This method is only for the outermost reader. 112 /// 113 /// Failure to follow this warning may result in misformed messages 114 /// being incorrectly reported as `Incomplete`. 115 // 116 // TODO this name is quite clumsy! 117 pub fn from_possibly_incomplete_slice(slice: &'a [u8]) -> Self { 118 Reader { 119 b: slice, 120 off: 0, 121 completeness: Completeness::PossiblyIncomplete, 122 } 123 } 124 /// Construct a new Reader from a slice of bytes, in tests 125 /// 126 /// This is equivalent to [`Reader::from_possibly_incomplete_slice`]. 127 /// It should be used in test cases, because that gives more precise 128 /// testing of the generation of incomplete data errors. 129 pub fn from_slice_for_test(slice: &'a [u8]) -> Self { 130 Self::from_possibly_incomplete_slice(slice) 131 } 132 /// Construct a new Reader from a 'Bytes' object. 133 pub fn from_bytes(b: &'a bytes::Bytes) -> Self { 134 Self::from_slice(b.as_ref()) 135 } 136 /// Return the total length of the slice in this reader, including 137 /// consumed bytes and remaining bytes. 138 pub fn total_len(&self) -> usize { 139 self.b.len() 140 } 141 /// Return the total number of bytes in this reader that have not 142 /// yet been read. 143 pub fn remaining(&self) -> usize { 144 self.b.len() - self.off 145 } 146 /// Consume this reader, and return a slice containing the remaining 147 /// bytes from its slice that it did not consume. 148 pub fn into_rest(self) -> &'a [u8] { 149 &self.b[self.off..] 150 } 151 /// Return the total number of bytes in this reader that have 152 /// already been read. 153 pub fn consumed(&self) -> usize { 154 self.off 155 } 156 /// Skip `n` bytes from the reader. 157 /// 158 /// Returns Ok on success. Throws MissingData or Incomplete if there were 159 /// not enough bytes to skip. 160 pub fn advance(&mut self, n: usize) -> Result<()> { 161 self.peek(n)?; 162 self.off += n; 163 Ok(()) 164 } 165 /// Check whether this reader is exhausted (out of bytes). 166 /// 167 /// Return Ok if it is, and Err(Error::ExtraneousBytes) 168 /// if there were extra bytes. 169 pub fn should_be_exhausted(&self) -> Result<()> { 170 if self.remaining() != 0 { 171 return Err(Error::ExtraneousBytes); 172 } 173 Ok(()) 174 } 175 /// Truncate this reader, so that no more than `n` bytes remain. 176 /// 177 /// Fewer than `n` bytes may remain if there were not enough bytes 178 /// to begin with. 179 pub fn truncate(&mut self, n: usize) { 180 if n < self.remaining() { 181 self.b = &self.b[..self.off + n]; 182 } 183 } 184 /// Try to return a slice of `n` bytes from this reader without 185 /// consuming them. 186 /// 187 /// On success, returns Ok(slice). If there are fewer than n 188 /// bytes, Throws MissingData or Incomplete if there were 189 /// not enough bytes to skip. 190 pub fn peek(&self, n: usize) -> Result<&'a [u8]> { 191 if let Some(deficit) = n 192 .checked_sub(self.remaining()) 193 .and_then(|d| d.try_into().ok()) 194 { 195 return Err(self.incomplete_error(deficit)); 196 } 197 198 Ok(&self.b[self.off..(n + self.off)]) 199 } 200 /// Try to consume and return a slice of `n` bytes from this reader. 201 /// 202 /// On success, returns Ok(Slice). If there are fewer than n 203 /// bytes, Throws MissingData or Incomplete. 204 /// 205 /// # Example 206 /// ``` 207 /// use tor_bytes::{Reader,Result}; 208 /// let m = b"Hello World"; 209 /// let mut b = Reader::from_slice(m); 210 /// assert_eq!(b.take(5)?, b"Hello"); 211 /// assert_eq!(b.take_u8()?, 0x20); 212 /// assert_eq!(b.take(5)?, b"World"); 213 /// b.should_be_exhausted()?; 214 /// # Result::Ok(()) 215 /// ``` 216 pub fn take(&mut self, n: usize) -> Result<&'a [u8]> { 217 let b = self.peek(n)?; 218 self.advance(n)?; 219 Ok(b) 220 } 221 /// Try to fill a provided buffer with bytes consumed from this reader. 222 /// 223 /// On success, the buffer will be filled with data from the 224 /// reader, the reader will advance by the length of the buffer, 225 /// and we'll return Ok(()). On failure the buffer will be 226 /// unchanged. 227 /// 228 /// # Example 229 /// ``` 230 /// use tor_bytes::Reader; 231 /// let m = b"Hello world"; 232 /// let mut v1 = vec![0; 5]; 233 /// let mut v2 = vec![0; 5]; 234 /// let mut b = Reader::from_slice(m); 235 /// b.take_into(&mut v1[..])?; 236 /// assert_eq!(b.take_u8()?, b' '); 237 /// b.take_into(&mut v2[..])?; 238 /// assert_eq!(&v1[..], b"Hello"); 239 /// assert_eq!(&v2[..], b"world"); 240 /// b.should_be_exhausted()?; 241 /// # tor_bytes::Result::Ok(()) 242 /// ``` 243 pub fn take_into(&mut self, buf: &mut [u8]) -> Result<()> { 244 let n = buf.len(); 245 let b = self.take(n)?; 246 buf.copy_from_slice(b); 247 Ok(()) 248 } 249 /// Try to consume and return a u8 from this reader. 250 pub fn take_u8(&mut self) -> Result<u8> { 251 let b = self.take(1)?; 252 Ok(b[0]) 253 } 254 /// Try to consume and return a big-endian u16 from this reader. 255 pub fn take_u16(&mut self) -> Result<u16> { 256 let b: [u8; 2] = self.extract()?; 257 let r = u16::from_be_bytes(b); 258 Ok(r) 259 } 260 /// Try to consume and return a big-endian u32 from this reader. 261 pub fn take_u32(&mut self) -> Result<u32> { 262 let b: [u8; 4] = self.extract()?; 263 let r = u32::from_be_bytes(b); 264 Ok(r) 265 } 266 /// Try to consume and return a big-endian u64 from this reader. 267 pub fn take_u64(&mut self) -> Result<u64> { 268 let b: [u8; 8] = self.extract()?; 269 let r = u64::from_be_bytes(b); 270 Ok(r) 271 } 272 /// Try to consume and return a big-endian u128 from this reader. 273 pub fn take_u128(&mut self) -> Result<u128> { 274 let b: [u8; 16] = self.extract()?; 275 let r = u128::from_be_bytes(b); 276 Ok(r) 277 } 278 /// Try to consume and return bytes from this buffer until we 279 /// encounter a terminating byte equal to `term`. 280 /// 281 /// On success, returns Ok(Slice), where the slice does not 282 /// include the terminating byte. Throws MissingData or Incomplete 283 /// if we do not find the terminating bytes. 284 /// 285 /// Advances the reader to the point immediately after the terminating 286 /// byte. 287 /// 288 /// # Example 289 /// ``` 290 /// use tor_bytes::{Reader,Result}; 291 /// let m = b"Hello\0wrld"; 292 /// let mut b = Reader::from_slice(m); 293 /// assert_eq!(b.take_until(0)?, b"Hello"); 294 /// assert_eq!(b.into_rest(), b"wrld"); 295 /// # Result::Ok(()) 296 /// ``` 297 pub fn take_until(&mut self, term: u8) -> Result<&'a [u8]> { 298 let pos = 299 self.b[self.off..] 300 .iter() 301 .position(|b| *b == term) 302 .ok_or(self.incomplete_error( 303 // 304 1.try_into().expect("1 == 0"), 305 ))?; 306 let result = self.take(pos)?; 307 self.advance(1)?; 308 Ok(result) 309 } 310 /// Consume and return all the remaining bytes, but do not consume the reader 311 /// 312 /// This can be useful if you need to possibly read either fixed-length data, 313 /// or variable length data eating the rest of the `Reader`. 314 /// 315 /// The `Reader` will be left devoid of further bytes. 316 /// Consider using `into_rest()` instead. 317 pub fn take_rest(&mut self) -> &'a [u8] { 318 self.take(self.remaining()) 319 .expect("taking remaining failed") 320 } 321 322 /// Consume and return all but the last `n` remaining bytes. 323 /// 324 /// Gives `Error::MissingData` if there are fewer than `n` remaining bytes. 325 /// 326 /// It is invalid to call this method on a `Reader` constructed with 327 /// [`Reader::from_possibly_incomplete_slice`]. (If we don't know where the 328 /// data actually ends, we can't take all but the last `n` bytes.) 329 /// Such calls cause an internal error. 330 /// 331 /// # Example 332 /// ``` 333 /// use tor_bytes::{Reader,Result}; 334 /// let m = b"Hello World"; 335 /// let mut b = Reader::from_slice(m); 336 /// assert_eq!(b.take_all_but(2)?, b"Hello Wor"); 337 /// assert_eq!(b.into_rest(), b"ld"); 338 /// # Result::Ok(()) 339 /// ``` 340 pub fn take_all_but(&mut self, n: usize) -> Result<&'a [u8]> { 341 match self.completeness { 342 Completeness::PossiblyIncomplete => { 343 return Err(Error::Bug(bad_api_usage!( 344 "Called take_all_but on a PossiblyIncomplete reader." 345 ))) 346 } 347 Completeness::SupposedlyComplete => {} 348 } 349 350 let n_to_take = self.remaining().checked_sub(n).ok_or(Error::MissingData)?; 351 352 let result = self 353 .take(n_to_take) 354 .map_err(into_internal!("Subtraction misled us somehow"))?; 355 debug_assert_eq!(self.remaining(), n); 356 Ok(result) 357 } 358 359 /// Try to decode and remove a Readable from this reader, using its 360 /// take_from() method. 361 /// 362 /// On failure, consumes nothing. 363 pub fn extract<E: Readable>(&mut self) -> Result<E> { 364 let off_orig = self.off; 365 let result = E::take_from(self); 366 if result.is_err() { 367 // We encountered an error; we should rewind. 368 self.off = off_orig; 369 } 370 result 371 } 372 373 /// Try to decode and remove `n` Readables from this reader, using the 374 /// Readable's take_from() method. 375 /// 376 /// On failure, consumes nothing. 377 pub fn extract_n<E: Readable>(&mut self, n: usize) -> Result<Vec<E>> { 378 // This `min` will help us defend against a pathological case where an 379 // attacker tells us that there are BIGNUM elements forthcoming, and our 380 // attempt to allocate `Vec::with_capacity(BIGNUM)` makes us panic. 381 // 382 // The `min` can be incorrect if E is somehow encodable in zero bytes 383 // (!?), but that will only cause our initial allocation to be too 384 // small. 385 // 386 // In practice, callers should always check that `n` is reasonable 387 // before calling this function, and protocol designers should not 388 // provide e.g. 32-bit counters for object types of which we should 389 // never allocate u32::MAX. 390 let n_alloc = std::cmp::min(n, self.remaining()); 391 let mut result = Vec::with_capacity(n_alloc); 392 let off_orig = self.off; 393 for _ in 0..n { 394 match E::take_from(self) { 395 Ok(item) => result.push(item), 396 Err(e) => { 397 // Encountered an error; we should rewind. 398 self.off = off_orig; 399 return Err(e); 400 } 401 } 402 } 403 Ok(result) 404 } 405 406 /// Decode something with a `u8` length field 407 /// 408 /// Prefer to use this function, rather than ad-hoc `take_u8` 409 /// and subsequent manual length checks. 410 /// Using this facility eliminates the need to separately keep track of the lengths. 411 /// 412 /// `read_nested` consumes a length field, 413 /// and provides the closure `f` with an inner `Reader` that 414 /// contains precisely that many bytes - 415 /// the bytes which follow the length field in the original reader. 416 /// If the closure is successful, `read_nested` checks that that inner reader is exhausted, 417 /// i.e. that the inner contents had the same length as was specified. 418 /// 419 /// The closure should read whatever is inside the nested structure 420 /// from the nested reader. 421 /// It may well want to use `take_rest`, to consume all of the counted bytes. 422 /// 423 /// On failure, the amount consumed is not specified. 424 pub fn read_nested_u8len<F, T>(&mut self, f: F) -> Result<T> 425 where 426 F: FnOnce(&mut Reader) -> Result<T>, 427 { 428 read_nested_generic::<u8, _, _>(self, f) 429 } 430 431 /// Start decoding something with a u16 length field 432 pub fn read_nested_u16len<F, T>(&mut self, f: F) -> Result<T> 433 where 434 F: FnOnce(&mut Reader) -> Result<T>, 435 { 436 read_nested_generic::<u16, _, _>(self, f) 437 } 438 439 /// Start decoding something with a u32 length field 440 pub fn read_nested_u32len<F, T>(&mut self, f: F) -> Result<T> 441 where 442 F: FnOnce(&mut Reader) -> Result<T>, 443 { 444 read_nested_generic::<u32, _, _>(self, f) 445 } 446 447 /// Return a cursor object describing the current position of this Reader 448 /// within its underlying byte stream. 449 /// 450 /// The resulting [`Cursor`] can be used with `range`, but nothing else. 451 /// 452 /// Note that having to use a `Cursor` is typically an anti-pattern: it 453 /// tends to indicate that whatever you're parsing could probably have a 454 /// better design that would better separate data from metadata. 455 /// Unfortunately, there are a few places like that in the Tor protocols. 456 // 457 // TODO: This could instead be a function that takes a closure, passes a 458 // reader to that closure, and returns the closure's output along with 459 // whatever the reader consumed. 460 pub fn cursor(&self) -> Cursor<'a> { 461 Cursor { 462 pos: self.off, 463 _phantom: std::marker::PhantomData, 464 } 465 } 466 467 /// Return the slice of bytes between the start cursor (inclusive) and end 468 /// cursor (exclusive). 469 /// 470 /// If the cursors are not in order, return an empty slice. 471 /// 472 /// This function is guaranteed not to panic if the inputs were generated 473 /// from a different Reader, but if so the byte slice that it returns will 474 /// not be meaningful. 475 pub fn range(&self, start: Cursor<'a>, end: Cursor<'a>) -> &'a [u8] { 476 if start.pos <= end.pos && end.pos <= self.b.len() { 477 &self.b[start.pos..end.pos] 478 } else { 479 &self.b[..0] 480 } 481 } 482 483 /// Returns the error that should be returned if we ran out of data 484 /// 485 /// For a usual `Reader` this is [`Error::MissingData`]. 486 /// For a reader from 487 /// [`Reader::from_possibly_incomplete_slice`] 488 /// it's [`Error::Incomplete`]. 489 pub fn incomplete_error(&self, deficit: NonZeroUsize) -> Error { 490 use Completeness as C; 491 use Error as E; 492 match self.completeness { 493 C::PossiblyIncomplete => E::Incomplete { 494 deficit: deficit.into(), 495 }, 496 C::SupposedlyComplete => E::MissingData, 497 } 498 } 499 } 500 501 /// A reference to a position within a [`Reader`]. 502 #[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)] 503 pub struct Cursor<'a> { 504 /// The underlying position within the reader. 505 pos: usize, 506 /// Used so that we can restrict the cursor to the lifetime of the 507 /// underlying byte slice. 508 _phantom: std::marker::PhantomData<&'a [u8]>, 509 } 510 511 /// Implementation of `read_nested_*` -- generic 512 fn read_nested_generic<L, F, T>(b: &mut Reader, f: F) -> Result<T> 513 where 514 F: FnOnce(&mut Reader) -> Result<T>, 515 L: Readable + Copy + Sized + TryInto<usize>, 516 { 517 let length: L = b.extract()?; 518 let length: usize = length.try_into().map_err(|_| Error::BadLengthValue)?; 519 let slice = b.take(length)?; 520 let mut inner = Reader::from_slice(slice); 521 let out = f(&mut inner)?; 522 inner.should_be_exhausted()?; 523 Ok(out) 524 } 525 526 #[cfg(test)] 527 mod tests { 528 #![allow(clippy::unwrap_used)] 529 #![allow(clippy::cognitive_complexity)] 530 use super::*; 531 #[test] 532 fn bytecursor_read_ok() { 533 let bytes = b"On a mountain halfway between Reno and Rome"; 534 let mut bc = Reader::from_slice(&bytes[..]); 535 536 assert_eq!(bc.consumed(), 0); 537 assert_eq!(bc.remaining(), 43); 538 assert_eq!(bc.total_len(), 43); 539 540 assert_eq!(bc.take(3).unwrap(), &b"On "[..]); 541 assert_eq!(bc.consumed(), 3); 542 543 assert_eq!(bc.take_u16().unwrap(), 0x6120); 544 assert_eq!(bc.take_u8().unwrap(), 0x6d); 545 assert_eq!(bc.take_u64().unwrap(), 0x6f756e7461696e20); 546 assert_eq!(bc.take_u32().unwrap(), 0x68616c66); 547 assert_eq!(bc.consumed(), 18); 548 assert_eq!(bc.remaining(), 25); 549 assert_eq!(bc.total_len(), 43); 550 551 assert_eq!(bc.peek(7).unwrap(), &b"way bet"[..]); 552 assert_eq!(bc.consumed(), 18); // no change 553 assert_eq!(bc.remaining(), 25); // no change 554 assert_eq!(bc.total_len(), 43); // no change 555 556 assert_eq!(bc.peek(7).unwrap(), &b"way bet"[..]); 557 assert_eq!(bc.consumed(), 18); // no change this time either. 558 559 bc.advance(12).unwrap(); 560 assert_eq!(bc.consumed(), 30); 561 assert_eq!(bc.remaining(), 13); 562 563 let rem = bc.into_rest(); 564 assert_eq!(rem, &b"Reno and Rome"[..]); 565 566 // now let's try consuming right up to the end. 567 let mut bc = Reader::from_slice(&bytes[..]); 568 bc.advance(22).unwrap(); 569 assert_eq!(bc.remaining(), 21); 570 let rem = bc.take(21).unwrap(); 571 assert_eq!(rem, &b"between Reno and Rome"[..]); 572 assert_eq!(bc.consumed(), 43); 573 assert_eq!(bc.remaining(), 0); 574 575 // We can still take a zero-length slice. 576 assert_eq!(bc.take(0).unwrap(), &b""[..]); 577 } 578 579 #[test] 580 fn read_u128() { 581 let bytes = bytes::Bytes::from(&b"irreproducibility?"[..]); // 18 bytes 582 let mut b = Reader::from_bytes(&bytes); 583 584 assert_eq!(b.take_u8().unwrap(), b'i'); 585 assert_eq!(b.take_u128().unwrap(), 0x72726570726f6475636962696c697479); 586 assert_eq!(b.remaining(), 1); 587 } 588 589 #[test] 590 fn bytecursor_read_missing() { 591 let bytes = b"1234567"; 592 let mut bc = Reader::from_slice_for_test(&bytes[..]); 593 594 assert_eq!(bc.consumed(), 0); 595 assert_eq!(bc.remaining(), 7); 596 assert_eq!(bc.total_len(), 7); 597 598 assert_eq!(bc.take_u64(), Err(Error::new_incomplete_for_test(1))); 599 assert_eq!(bc.take(8), Err(Error::new_incomplete_for_test(1))); 600 assert_eq!(bc.peek(8), Err(Error::new_incomplete_for_test(1))); 601 602 assert_eq!(bc.consumed(), 0); 603 assert_eq!(bc.remaining(), 7); 604 assert_eq!(bc.total_len(), 7); 605 606 assert_eq!(bc.take_u32().unwrap(), 0x31323334); // get 4 bytes. 3 left. 607 assert_eq!(bc.take_u32(), Err(Error::new_incomplete_for_test(1))); 608 609 assert_eq!(bc.consumed(), 4); 610 assert_eq!(bc.remaining(), 3); 611 assert_eq!(bc.total_len(), 7); 612 613 assert_eq!(bc.take_u16().unwrap(), 0x3536); // get 2 bytes. 1 left. 614 assert_eq!(bc.take_u16(), Err(Error::new_incomplete_for_test(1))); 615 616 assert_eq!(bc.consumed(), 6); 617 assert_eq!(bc.remaining(), 1); 618 assert_eq!(bc.total_len(), 7); 619 620 assert_eq!(bc.take_u8().unwrap(), 0x37); // get 1 byte. 0 left. 621 assert_eq!(bc.take_u8(), Err(Error::new_incomplete_for_test(1))); 622 623 assert_eq!(bc.consumed(), 7); 624 assert_eq!(bc.remaining(), 0); 625 assert_eq!(bc.total_len(), 7); 626 } 627 628 #[test] 629 fn advance_too_far() { 630 let bytes = b"12345"; 631 let mut b = Reader::from_slice_for_test(&bytes[..]); 632 assert_eq!(b.remaining(), 5); 633 assert_eq!(b.advance(16), Err(Error::new_incomplete_for_test(11))); 634 assert_eq!(b.remaining(), 5); 635 assert_eq!(b.advance(5), Ok(())); 636 assert_eq!(b.remaining(), 0); 637 } 638 639 #[test] 640 fn truncate() { 641 let bytes = b"Hello universe!!!1!"; 642 let mut b = Reader::from_slice_for_test(&bytes[..]); 643 644 assert_eq!(b.take(5).unwrap(), &b"Hello"[..]); 645 assert_eq!(b.remaining(), 14); 646 assert_eq!(b.consumed(), 5); 647 b.truncate(9); 648 assert_eq!(b.remaining(), 9); 649 assert_eq!(b.consumed(), 5); 650 assert_eq!(b.take_u8().unwrap(), 0x20); 651 assert_eq!(b.into_rest(), &b"universe"[..]); 652 } 653 654 #[test] 655 fn exhaust() { 656 let b = Reader::from_slice_for_test(&b""[..]); 657 assert_eq!(b.should_be_exhausted(), Ok(())); 658 659 let mut b = Reader::from_slice_for_test(&b"outis"[..]); 660 assert_eq!(b.should_be_exhausted(), Err(Error::ExtraneousBytes)); 661 b.take(4).unwrap(); 662 assert_eq!(b.should_be_exhausted(), Err(Error::ExtraneousBytes)); 663 b.take(1).unwrap(); 664 assert_eq!(b.should_be_exhausted(), Ok(())); 665 } 666 667 #[test] 668 fn take_rest() { 669 let mut b = Reader::from_slice_for_test(b"si vales valeo"); 670 assert_eq!(b.take(3).unwrap(), b"si "); 671 assert_eq!(b.take_rest(), b"vales valeo"); 672 assert_eq!(b.take_rest(), b""); 673 } 674 675 #[test] 676 fn take_until() { 677 let mut b = Reader::from_slice_for_test(&b"si vales valeo"[..]); 678 assert_eq!(b.take_until(b' ').unwrap(), &b"si"[..]); 679 assert_eq!(b.take_until(b' ').unwrap(), &b"vales"[..]); 680 assert_eq!(b.take_until(b' '), Err(Error::new_incomplete_for_test(1))); 681 } 682 683 #[test] 684 fn truncate_badly() { 685 let mut b = Reader::from_slice_for_test(&b"abcdefg"[..]); 686 b.truncate(1000); 687 assert_eq!(b.total_len(), 7); 688 assert_eq!(b.remaining(), 7); 689 } 690 691 #[test] 692 fn nested_good() { 693 let mut b = Reader::from_slice_for_test(b"abc\0\0\x04defghijkl"); 694 assert_eq!(b.take(3).unwrap(), b"abc"); 695 696 b.read_nested_u16len(|s| { 697 assert!(s.should_be_exhausted().is_ok()); 698 Ok(()) 699 }) 700 .unwrap(); 701 702 b.read_nested_u8len(|s| { 703 assert_eq!(s.take(4).unwrap(), b"defg"); 704 assert!(s.should_be_exhausted().is_ok()); 705 Ok(()) 706 }) 707 .unwrap(); 708 709 assert_eq!(b.take(2).unwrap(), b"hi"); 710 } 711 712 #[test] 713 fn nested_bad() { 714 let mut b = Reader::from_slice_for_test(b"................"); 715 assert_eq!( 716 read_nested_generic::<u128, _, ()>(&mut b, |_| panic!()) 717 .err() 718 .unwrap(), 719 Error::BadLengthValue 720 ); 721 722 let mut b = Reader::from_slice_for_test(b"................"); 723 assert_eq!( 724 b.read_nested_u32len::<_, ()>(|_| panic!()).err().unwrap(), 725 Error::new_incomplete_for_test(774778414 - (16 - 4)) 726 ); 727 } 728 729 #[test] 730 fn nested_inner_bad() { 731 let mut b = Reader::from_slice_for_test(&[1, 66]); 732 assert_eq!( 733 b.read_nested_u8len(|b| b.take_u32()), 734 Err(Error::MissingData), 735 ); 736 } 737 738 #[test] 739 fn incomplete_slice() { 740 // Test specifically the from_possibly_incomplete_slice constructor - 741 // ie, deliberately don't use Reader::from_slice_for_test. 742 let mut b = Reader::from_possibly_incomplete_slice(&[]); 743 assert_eq!(b.take_u32(), Err(Error::new_incomplete_for_test(4))); 744 } 745 746 #[test] 747 fn extract() { 748 // For example purposes, declare a length-then-bytes string type. 749 #[derive(Debug)] 750 struct LenEnc(Vec<u8>); 751 impl Readable for LenEnc { 752 fn take_from(b: &mut Reader<'_>) -> Result<Self> { 753 let length = b.take_u8()?; 754 let content = b.take(length as usize)?.into(); 755 Ok(LenEnc(content)) 756 } 757 } 758 759 let bytes = b"\x04this\x02is\x09sometimes\x01a\x06string!"; 760 let mut b = Reader::from_slice_for_test(&bytes[..]); 761 762 let le: LenEnc = b.extract().unwrap(); 763 assert_eq!(&le.0[..], &b"this"[..]); 764 765 let les: Vec<LenEnc> = b.extract_n(4).unwrap(); 766 assert_eq!(&les[3].0[..], &b"string"[..]); 767 768 assert_eq!(b.remaining(), 1); 769 770 // Make sure that we don't advance on a failing extract(). 771 let le: Result<LenEnc> = b.extract(); 772 assert_eq!(le.unwrap_err(), Error::new_incomplete_for_test(33)); 773 assert_eq!(b.remaining(), 1); 774 775 // Make sure that we don't advance on a failing extract_n() 776 let mut b = Reader::from_slice_for_test(&bytes[..]); 777 assert_eq!(b.remaining(), 28); 778 let les: Result<Vec<LenEnc>> = b.extract_n(10); 779 assert_eq!(les.unwrap_err(), Error::new_incomplete_for_test(33)); 780 assert_eq!(b.remaining(), 28); 781 } 782 783 #[test] 784 fn cursor() -> Result<()> { 785 let alphabet = b"abcdefghijklmnopqrstuvwxyz"; 786 let mut b = Reader::from_slice_for_test(&alphabet[..]); 787 788 let c1 = b.cursor(); 789 let _ = b.take_u16()?; 790 let c2 = b.cursor(); 791 let c2b = b.cursor(); 792 b.advance(7)?; 793 let c3 = b.cursor(); 794 795 assert_eq!(b.range(c1, c2), &b"ab"[..]); 796 assert_eq!(b.range(c2, c3), &b"cdefghi"[..]); 797 assert_eq!(b.range(c1, c3), &b"abcdefghi"[..]); 798 assert_eq!(b.range(c1, c1), &b""[..]); 799 assert_eq!(b.range(c3, c1), &b""[..]); 800 assert_eq!(c2, c2b); 801 assert!(c1 < c2); 802 assert!(c2 < c3); 803 804 Ok(()) 805 } 806 807 #[test] 808 fn take_all_but() -> Result<()> { 809 let message = b"byte manipulation for fun and (non)-profit"; 810 811 // Case 1: Successful, complete reader 812 // (Can't use from_slice_for_test here: that's a possibly-incomplete reader.) 813 let mut b = Reader::from_slice(message); 814 assert_eq!(b.take_all_but(6)?, b"byte manipulation for fun and (non)-"); 815 assert_eq!(b.into_rest(), b"profit"); 816 817 // Case 1b: Successful, take nothing, complete reader. 818 let mut b = Reader::from_slice(message); 819 assert_eq!(b.take_all_but(message.len())?, b""); 820 assert_eq!(b.into_rest(), message); 821 822 // Case 1c: Successful, take everything, complete reader. 823 let mut b = Reader::from_slice(message); 824 assert_eq!(b.take_all_but(0)?, message); 825 assert_eq!(b.into_rest(), b""); 826 827 // Case 2: Unsuccessful, complete reader 828 let mut b = Reader::from_slice(message); 829 assert!(matches!( 830 b.take_all_but(message.len() + 1), 831 Err(Error::MissingData) 832 )); 833 834 // Case 3: Anything, incomplete reader. 835 let mut b = Reader::from_possibly_incomplete_slice(message); 836 assert!(matches!(b.take_all_but(6), Err(Error::Bug(_)))); 837 838 Ok(()) 839 } 840 }