tor_bytes/reader.rs
1//! Internal: Declare the Reader type for tor-bytes
2
3use tor_error::{bad_api_usage, into_internal};
4
5use crate::{Error, Readable, Result};
6use 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/// ```
53pub 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)]
69enum 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
80impl<'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 malformed 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)]
503pub 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
512fn read_nested_generic<L, F, T>(b: &mut Reader, f: F) -> Result<T>
513where
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)]
527mod 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}