/ crates / tor-bytes / src / reader.rs
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  }