1 #[cfg(feature = "alloc")]
2 use alloc::{vec, vec::Vec};
3 #[cfg(feature = "std")]
4 use core::cmp;
5 use core::mem;
6 
7 #[cfg(feature = "std")]
8 use std::io::{self, Read as StdRead};
9 
10 use crate::error::{Error, ErrorCode, Result};
11 
12 #[cfg(not(feature = "unsealed_read_write"))]
13 /// Trait used by the deserializer for iterating over input.
14 ///
15 /// This trait is sealed by default, enabling the `unsealed_read_write` feature removes this bound
16 /// to allow objects outside of this crate to implement this trait.
17 pub trait Read<'de>: private::Sealed {
18     #[doc(hidden)]
19     /// Read n bytes from the input.
20     ///
21     /// Implementations that can are asked to return a slice with a Long lifetime that outlives the
22     /// decoder, but others (eg. ones that need to allocate the data into a temporary buffer) can
23     /// return it with a Short lifetime that just lives for the time of read's mutable borrow of
24     /// the reader.
25     ///
26     /// This may, as a side effect, clear the reader's scratch buffer (as the provided
27     /// implementation does).
28 
29     // A more appropriate lifetime setup for this (that would allow the Deserializer::convert_str
30     // to stay a function) would be something like `fn read<'a, 'r: 'a>(&'a mut 'r immut self, ...) -> ...
31     // EitherLifetime<'r, 'de>>`, which borrows self mutably for the duration of the function and
32     // downgrates that reference to an immutable one that outlives the result (protecting the
33     // scratch buffer from changes), but alas, that can't be expressed (yet?).
read<'a>(&'a mut self, n: usize) -> Result<EitherLifetime<'a, 'de>>34     fn read<'a>(&'a mut self, n: usize) -> Result<EitherLifetime<'a, 'de>> {
35         self.clear_buffer();
36         self.read_to_buffer(n)?;
37 
38         Ok(self.take_buffer())
39     }
40 
41     #[doc(hidden)]
next(&mut self) -> Result<Option<u8>>42     fn next(&mut self) -> Result<Option<u8>>;
43 
44     #[doc(hidden)]
peek(&mut self) -> Result<Option<u8>>45     fn peek(&mut self) -> Result<Option<u8>>;
46 
47     #[doc(hidden)]
clear_buffer(&mut self)48     fn clear_buffer(&mut self);
49 
50     #[doc(hidden)]
read_to_buffer(&mut self, n: usize) -> Result<()>51     fn read_to_buffer(&mut self, n: usize) -> Result<()>;
52 
53     #[doc(hidden)]
take_buffer<'a>(&'a mut self) -> EitherLifetime<'a, 'de>54     fn take_buffer<'a>(&'a mut self) -> EitherLifetime<'a, 'de>;
55 
56     #[doc(hidden)]
read_into(&mut self, buf: &mut [u8]) -> Result<()>57     fn read_into(&mut self, buf: &mut [u8]) -> Result<()>;
58 
59     #[doc(hidden)]
discard(&mut self)60     fn discard(&mut self);
61 
62     #[doc(hidden)]
offset(&self) -> u6463     fn offset(&self) -> u64;
64 }
65 
66 #[cfg(feature = "unsealed_read_write")]
67 /// Trait used by the deserializer for iterating over input.
68 pub trait Read<'de> {
69     /// Read n bytes from the input.
70     ///
71     /// Implementations that can are asked to return a slice with a Long lifetime that outlives the
72     /// decoder, but others (eg. ones that need to allocate the data into a temporary buffer) can
73     /// return it with a Short lifetime that just lives for the time of read's mutable borrow of
74     /// the reader.
75     ///
76     /// This may, as a side effect, clear the reader's scratch buffer (as the provided
77     /// implementation does).
78 
79     // A more appropriate lifetime setup for this (that would allow the Deserializer::convert_str
80     // to stay a function) would be something like `fn read<'a, 'r: 'a>(&'a mut 'r immut self, ...) -> ...
81     // EitherLifetime<'r, 'de>>`, which borrows self mutably for the duration of the function and
82     // downgrates that reference to an immutable one that outlives the result (protecting the
83     // scratch buffer from changes), but alas, that can't be expressed (yet?).
read<'a>(&'a mut self, n: usize) -> Result<EitherLifetime<'a, 'de>>84     fn read<'a>(&'a mut self, n: usize) -> Result<EitherLifetime<'a, 'de>> {
85         self.clear_buffer();
86         self.read_to_buffer(n)?;
87 
88         Ok(self.take_buffer())
89     }
90 
91     /// Read the next byte from the input, if any.
next(&mut self) -> Result<Option<u8>>92     fn next(&mut self) -> Result<Option<u8>>;
93 
94     /// Peek at the next byte of the input, if any. This does not advance the reader, so the result
95     /// of this function will remain the same until a read or clear occurs.
peek(&mut self) -> Result<Option<u8>>96     fn peek(&mut self) -> Result<Option<u8>>;
97 
98     /// Clear the underlying scratch buffer
clear_buffer(&mut self)99     fn clear_buffer(&mut self);
100 
101     /// Append n bytes from the reader to the reader's scratch buffer (without clearing it)
read_to_buffer(&mut self, n: usize) -> Result<()>102     fn read_to_buffer(&mut self, n: usize) -> Result<()>;
103 
104     /// Read out everything accumulated in the reader's scratch buffer. This may, as a side effect,
105     /// clear it.
take_buffer<'a>(&'a mut self) -> EitherLifetime<'a, 'de>106     fn take_buffer<'a>(&'a mut self) -> EitherLifetime<'a, 'de>;
107 
108     /// Read from the input until `buf` is full or end of input is encountered.
read_into(&mut self, buf: &mut [u8]) -> Result<()>109     fn read_into(&mut self, buf: &mut [u8]) -> Result<()>;
110 
111     /// Discard any data read by `peek`.
discard(&mut self)112     fn discard(&mut self);
113 
114     /// Returns the offset from the start of the reader.
offset(&self) -> u64115     fn offset(&self) -> u64;
116 }
117 
118 /// Represents a reader that can return its current position
119 pub trait Offset {
byte_offset(&self) -> usize120     fn byte_offset(&self) -> usize;
121 }
122 
123 /// Represents a buffer with one of two lifetimes.
124 pub enum EitherLifetime<'short, 'long> {
125     /// The short lifetime
126     Short(&'short [u8]),
127     /// The long lifetime
128     Long(&'long [u8]),
129 }
130 
131 #[cfg(not(feature = "unsealed_read_write"))]
132 mod private {
133     pub trait Sealed {}
134 }
135 
136 /// CBOR input source that reads from a std::io input stream.
137 #[cfg(feature = "std")]
138 #[derive(Debug)]
139 pub struct IoRead<R>
140 where
141     R: io::Read,
142 {
143     reader: OffsetReader<R>,
144     scratch: Vec<u8>,
145     ch: Option<u8>,
146 }
147 
148 #[cfg(feature = "std")]
149 impl<R> IoRead<R>
150 where
151     R: io::Read,
152 {
153     /// Creates a new CBOR input source to read from a std::io input stream.
new(reader: R) -> IoRead<R>154     pub fn new(reader: R) -> IoRead<R> {
155         IoRead {
156             reader: OffsetReader { reader, offset: 0 },
157             scratch: vec![],
158             ch: None,
159         }
160     }
161 
162     #[inline]
next_inner(&mut self) -> Result<Option<u8>>163     fn next_inner(&mut self) -> Result<Option<u8>> {
164         let mut buf = [0; 1];
165         loop {
166             match self.reader.read(&mut buf) {
167                 Ok(0) => return Ok(None),
168                 Ok(_) => return Ok(Some(buf[0])),
169                 Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
170                 Err(e) => return Err(Error::io(e)),
171             }
172         }
173     }
174 }
175 
176 #[cfg(all(feature = "std", not(feature = "unsealed_read_write")))]
177 impl<R> private::Sealed for IoRead<R> where R: io::Read {}
178 
179 #[cfg(feature = "std")]
180 impl<'de, R> Read<'de> for IoRead<R>
181 where
182     R: io::Read,
183 {
184     #[inline]
next(&mut self) -> Result<Option<u8>>185     fn next(&mut self) -> Result<Option<u8>> {
186         match self.ch.take() {
187             Some(ch) => Ok(Some(ch)),
188             None => self.next_inner(),
189         }
190     }
191 
192     #[inline]
peek(&mut self) -> Result<Option<u8>>193     fn peek(&mut self) -> Result<Option<u8>> {
194         match self.ch {
195             Some(ch) => Ok(Some(ch)),
196             None => {
197                 self.ch = self.next_inner()?;
198                 Ok(self.ch)
199             }
200         }
201     }
202 
read_to_buffer(&mut self, mut n: usize) -> Result<()>203     fn read_to_buffer(&mut self, mut n: usize) -> Result<()> {
204         // defend against malicious input pretending to be huge strings by limiting growth
205         self.scratch.reserve(cmp::min(n, 16 * 1024));
206 
207         if n == 0 {
208             return Ok(());
209         }
210 
211         if let Some(ch) = self.ch.take() {
212             self.scratch.push(ch);
213             n -= 1;
214         }
215 
216         // n == 0 is OK here and needs no further special treatment
217 
218         let transfer_result = {
219             // Prepare for take() (which consumes its reader) by creating a reference adaptor
220             // that'll only live in this block
221             let reference = self.reader.by_ref();
222             // Append the first n bytes of the reader to the scratch vector (or up to
223             // an error or EOF indicated by a shorter read)
224             let mut taken = reference.take(n as u64);
225             taken.read_to_end(&mut self.scratch)
226         };
227 
228         match transfer_result {
229             Ok(r) if r == n => Ok(()),
230             Ok(_) => Err(Error::syntax(
231                 ErrorCode::EofWhileParsingValue,
232                 self.offset(),
233             )),
234             Err(e) => Err(Error::io(e)),
235         }
236     }
237 
clear_buffer(&mut self)238     fn clear_buffer(&mut self) {
239         self.scratch.clear();
240     }
241 
take_buffer<'a>(&'a mut self) -> EitherLifetime<'a, 'de>242     fn take_buffer<'a>(&'a mut self) -> EitherLifetime<'a, 'de> {
243         EitherLifetime::Short(&self.scratch)
244     }
245 
read_into(&mut self, buf: &mut [u8]) -> Result<()>246     fn read_into(&mut self, buf: &mut [u8]) -> Result<()> {
247         self.reader.read_exact(buf).map_err(|e| {
248             if e.kind() == io::ErrorKind::UnexpectedEof {
249                 Error::syntax(ErrorCode::EofWhileParsingValue, self.offset())
250             } else {
251                 Error::io(e)
252             }
253         })
254     }
255 
256     #[inline]
discard(&mut self)257     fn discard(&mut self) {
258         self.ch = None;
259     }
260 
offset(&self) -> u64261     fn offset(&self) -> u64 {
262         self.reader.offset
263     }
264 }
265 
266 #[cfg(feature = "std")]
267 impl<R> Offset for IoRead<R>
268 where
269     R: std::io::Read,
270 {
byte_offset(&self) -> usize271     fn byte_offset(&self) -> usize {
272         self.offset() as usize
273     }
274 }
275 
276 #[cfg(feature = "std")]
277 #[derive(Debug)]
278 struct OffsetReader<R> {
279     reader: R,
280     offset: u64,
281 }
282 
283 #[cfg(feature = "std")]
284 impl<R> io::Read for OffsetReader<R>
285 where
286     R: io::Read,
287 {
288     #[inline]
read(&mut self, buf: &mut [u8]) -> io::Result<usize>289     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
290         let r = self.reader.read(buf);
291         if let Ok(count) = r {
292             self.offset += count as u64;
293         }
294         r
295     }
296 }
297 
298 /// A CBOR input source that reads from a slice of bytes.
299 #[cfg(any(feature = "std", feature = "alloc"))]
300 #[derive(Debug)]
301 pub struct SliceRead<'a> {
302     slice: &'a [u8],
303     scratch: Vec<u8>,
304     index: usize,
305 }
306 
307 #[cfg(any(feature = "std", feature = "alloc"))]
308 impl<'a> SliceRead<'a> {
309     /// Creates a CBOR input source to read from a slice of bytes.
new(slice: &'a [u8]) -> SliceRead<'a>310     pub fn new(slice: &'a [u8]) -> SliceRead<'a> {
311         SliceRead {
312             slice,
313             scratch: vec![],
314             index: 0,
315         }
316     }
317 
end(&self, n: usize) -> Result<usize>318     fn end(&self, n: usize) -> Result<usize> {
319         match self.index.checked_add(n) {
320             Some(end) if end <= self.slice.len() => Ok(end),
321             _ => Err(Error::syntax(
322                 ErrorCode::EofWhileParsingValue,
323                 self.slice.len() as u64,
324             )),
325         }
326     }
327 }
328 
329 #[cfg(any(feature = "std", feature = "alloc"))]
330 impl<'a> Offset for SliceRead<'a> {
331     #[inline]
byte_offset(&self) -> usize332     fn byte_offset(&self) -> usize {
333         self.index
334     }
335 }
336 
337 #[cfg(all(
338     any(feature = "std", feature = "alloc"),
339     not(feature = "unsealed_read_write")
340 ))]
341 impl<'a> private::Sealed for SliceRead<'a> {}
342 
343 #[cfg(any(feature = "std", feature = "alloc"))]
344 impl<'a> Read<'a> for SliceRead<'a> {
345     #[inline]
next(&mut self) -> Result<Option<u8>>346     fn next(&mut self) -> Result<Option<u8>> {
347         Ok(if self.index < self.slice.len() {
348             let ch = self.slice[self.index];
349             self.index += 1;
350             Some(ch)
351         } else {
352             None
353         })
354     }
355 
356     #[inline]
peek(&mut self) -> Result<Option<u8>>357     fn peek(&mut self) -> Result<Option<u8>> {
358         Ok(if self.index < self.slice.len() {
359             Some(self.slice[self.index])
360         } else {
361             None
362         })
363     }
364 
clear_buffer(&mut self)365     fn clear_buffer(&mut self) {
366         self.scratch.clear();
367     }
368 
read_to_buffer(&mut self, n: usize) -> Result<()>369     fn read_to_buffer(&mut self, n: usize) -> Result<()> {
370         let end = self.end(n)?;
371         let slice = &self.slice[self.index..end];
372         self.scratch.extend_from_slice(slice);
373         self.index = end;
374 
375         Ok(())
376     }
377 
378     #[inline]
read<'b>(&'b mut self, n: usize) -> Result<EitherLifetime<'b, 'a>>379     fn read<'b>(&'b mut self, n: usize) -> Result<EitherLifetime<'b, 'a>> {
380         let end = self.end(n)?;
381         let slice = &self.slice[self.index..end];
382         self.index = end;
383         Ok(EitherLifetime::Long(slice))
384     }
385 
take_buffer<'b>(&'b mut self) -> EitherLifetime<'b, 'a>386     fn take_buffer<'b>(&'b mut self) -> EitherLifetime<'b, 'a> {
387         EitherLifetime::Short(&self.scratch)
388     }
389 
390     #[inline]
read_into(&mut self, buf: &mut [u8]) -> Result<()>391     fn read_into(&mut self, buf: &mut [u8]) -> Result<()> {
392         let end = self.end(buf.len())?;
393         buf.copy_from_slice(&self.slice[self.index..end]);
394         self.index = end;
395         Ok(())
396     }
397 
398     #[inline]
discard(&mut self)399     fn discard(&mut self) {
400         self.index += 1;
401     }
402 
offset(&self) -> u64403     fn offset(&self) -> u64 {
404         self.index as u64
405     }
406 }
407 
408 /// A CBOR input source that reads from a slice of bytes using a fixed size scratch buffer.
409 ///
410 /// [`SliceRead`](struct.SliceRead.html) and [`MutSliceRead`](struct.MutSliceRead.html) are usually
411 /// preferred over this, as they can handle indefinite length items.
412 #[derive(Debug)]
413 pub struct SliceReadFixed<'a, 'b> {
414     slice: &'a [u8],
415     scratch: &'b mut [u8],
416     index: usize,
417     scratch_index: usize,
418 }
419 
420 impl<'a, 'b> SliceReadFixed<'a, 'b> {
421     /// Creates a CBOR input source to read from a slice of bytes, backed by a scratch buffer.
new(slice: &'a [u8], scratch: &'b mut [u8]) -> SliceReadFixed<'a, 'b>422     pub fn new(slice: &'a [u8], scratch: &'b mut [u8]) -> SliceReadFixed<'a, 'b> {
423         SliceReadFixed {
424             slice,
425             scratch,
426             index: 0,
427             scratch_index: 0,
428         }
429     }
430 
end(&self, n: usize) -> Result<usize>431     fn end(&self, n: usize) -> Result<usize> {
432         match self.index.checked_add(n) {
433             Some(end) if end <= self.slice.len() => Ok(end),
434             _ => Err(Error::syntax(
435                 ErrorCode::EofWhileParsingValue,
436                 self.slice.len() as u64,
437             )),
438         }
439     }
440 
scratch_end(&self, n: usize) -> Result<usize>441     fn scratch_end(&self, n: usize) -> Result<usize> {
442         match self.scratch_index.checked_add(n) {
443             Some(end) if end <= self.scratch.len() => Ok(end),
444             _ => Err(Error::scratch_too_small(self.index as u64)),
445         }
446     }
447 }
448 
449 #[cfg(not(feature = "unsealed_read_write"))]
450 impl<'a, 'b> private::Sealed for SliceReadFixed<'a, 'b> {}
451 
452 impl<'a, 'b> Read<'a> for SliceReadFixed<'a, 'b> {
453     #[inline]
next(&mut self) -> Result<Option<u8>>454     fn next(&mut self) -> Result<Option<u8>> {
455         Ok(if self.index < self.slice.len() {
456             let ch = self.slice[self.index];
457             self.index += 1;
458             Some(ch)
459         } else {
460             None
461         })
462     }
463 
464     #[inline]
peek(&mut self) -> Result<Option<u8>>465     fn peek(&mut self) -> Result<Option<u8>> {
466         Ok(if self.index < self.slice.len() {
467             Some(self.slice[self.index])
468         } else {
469             None
470         })
471     }
472 
clear_buffer(&mut self)473     fn clear_buffer(&mut self) {
474         self.scratch_index = 0;
475     }
476 
read_to_buffer(&mut self, n: usize) -> Result<()>477     fn read_to_buffer(&mut self, n: usize) -> Result<()> {
478         let end = self.end(n)?;
479         let scratch_end = self.scratch_end(n)?;
480         let slice = &self.slice[self.index..end];
481         self.scratch[self.scratch_index..scratch_end].copy_from_slice(&slice);
482         self.index = end;
483         self.scratch_index = scratch_end;
484 
485         Ok(())
486     }
487 
read<'c>(&'c mut self, n: usize) -> Result<EitherLifetime<'c, 'a>>488     fn read<'c>(&'c mut self, n: usize) -> Result<EitherLifetime<'c, 'a>> {
489         let end = self.end(n)?;
490         let slice = &self.slice[self.index..end];
491         self.index = end;
492         Ok(EitherLifetime::Long(slice))
493     }
494 
take_buffer<'c>(&'c mut self) -> EitherLifetime<'c, 'a>495     fn take_buffer<'c>(&'c mut self) -> EitherLifetime<'c, 'a> {
496         EitherLifetime::Short(&self.scratch[0..self.scratch_index])
497     }
498 
499     #[inline]
read_into(&mut self, buf: &mut [u8]) -> Result<()>500     fn read_into(&mut self, buf: &mut [u8]) -> Result<()> {
501         let end = self.end(buf.len())?;
502         buf.copy_from_slice(&self.slice[self.index..end]);
503         self.index = end;
504         Ok(())
505     }
506 
507     #[inline]
discard(&mut self)508     fn discard(&mut self) {
509         self.index += 1;
510     }
511 
offset(&self) -> u64512     fn offset(&self) -> u64 {
513         self.index as u64
514     }
515 }
516 
517 #[cfg(any(feature = "std", feature = "alloc"))]
518 impl<'a, 'b> Offset for SliceReadFixed<'a, 'b> {
519     #[inline]
byte_offset(&self) -> usize520     fn byte_offset(&self) -> usize {
521         self.index
522     }
523 }
524 
525 /// A CBOR input source that reads from a slice of bytes, and can move data around internally to
526 /// reassemble indefinite strings without the need of an allocated scratch buffer.
527 #[derive(Debug)]
528 pub struct MutSliceRead<'a> {
529     /// A complete view of the reader's data. It is promised that bytes before buffer_end are not
530     /// mutated any more.
531     slice: &'a mut [u8],
532     /// Read cursor position in slice
533     index: usize,
534     /// Number of bytes already discarded from the slice
535     before: usize,
536     /// End of the buffer area that contains all bytes read_into_buffer. This is always <= index.
537     buffer_end: usize,
538 }
539 
540 impl<'a> MutSliceRead<'a> {
541     /// Creates a CBOR input source to read from a slice of bytes.
new(slice: &'a mut [u8]) -> MutSliceRead<'a>542     pub fn new(slice: &'a mut [u8]) -> MutSliceRead<'a> {
543         MutSliceRead {
544             slice,
545             index: 0,
546             before: 0,
547             buffer_end: 0,
548         }
549     }
550 
end(&self, n: usize) -> Result<usize>551     fn end(&self, n: usize) -> Result<usize> {
552         match self.index.checked_add(n) {
553             Some(end) if end <= self.slice.len() => Ok(end),
554             _ => Err(Error::syntax(
555                 ErrorCode::EofWhileParsingValue,
556                 self.slice.len() as u64,
557             )),
558         }
559     }
560 }
561 
562 #[cfg(not(feature = "unsealed_read_write"))]
563 impl<'a> private::Sealed for MutSliceRead<'a> {}
564 
565 impl<'a> Read<'a> for MutSliceRead<'a> {
566     #[inline]
next(&mut self) -> Result<Option<u8>>567     fn next(&mut self) -> Result<Option<u8>> {
568         // This is duplicated from SliceRead, can that be eased?
569         Ok(if self.index < self.slice.len() {
570             let ch = self.slice[self.index];
571             self.index += 1;
572             Some(ch)
573         } else {
574             None
575         })
576     }
577 
578     #[inline]
peek(&mut self) -> Result<Option<u8>>579     fn peek(&mut self) -> Result<Option<u8>> {
580         // This is duplicated from SliceRead, can that be eased?
581         Ok(if self.index < self.slice.len() {
582             Some(self.slice[self.index])
583         } else {
584             None
585         })
586     }
587 
clear_buffer(&mut self)588     fn clear_buffer(&mut self) {
589         self.slice = &mut mem::replace(&mut self.slice, &mut [])[self.index..];
590         self.before += self.index;
591         self.index = 0;
592         self.buffer_end = 0;
593     }
594 
read_to_buffer(&mut self, n: usize) -> Result<()>595     fn read_to_buffer(&mut self, n: usize) -> Result<()> {
596         let end = self.end(n)?;
597         debug_assert!(
598             self.buffer_end <= self.index,
599             "MutSliceRead invariant violated: scratch buffer exceeds index"
600         );
601         self.slice[self.buffer_end..end].rotate_left(self.index - self.buffer_end);
602         self.buffer_end += n;
603         self.index = end;
604 
605         Ok(())
606     }
607 
take_buffer<'b>(&'b mut self) -> EitherLifetime<'b, 'a>608     fn take_buffer<'b>(&'b mut self) -> EitherLifetime<'b, 'a> {
609         let (left, right) = mem::replace(&mut self.slice, &mut []).split_at_mut(self.index);
610         self.slice = right;
611         self.before += self.index;
612         self.index = 0;
613 
614         let left = &left[..self.buffer_end];
615         self.buffer_end = 0;
616 
617         EitherLifetime::Long(left)
618     }
619 
620     #[inline]
read_into(&mut self, buf: &mut [u8]) -> Result<()>621     fn read_into(&mut self, buf: &mut [u8]) -> Result<()> {
622         // This is duplicated from SliceRead, can that be eased?
623         let end = self.end(buf.len())?;
624         buf.copy_from_slice(&self.slice[self.index..end]);
625         self.index = end;
626         Ok(())
627     }
628 
629     #[inline]
discard(&mut self)630     fn discard(&mut self) {
631         self.index += 1;
632     }
633 
offset(&self) -> u64634     fn offset(&self) -> u64 {
635         (self.before + self.index) as u64
636     }
637 }
638