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