summaryrefslogtreecommitdiffstats
path: root/vendor/der/src/reader
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
commit9835e2ae736235810b4ea1c162ca5e65c547e770 (patch)
tree3fcebf40ed70e581d776a8a4c65923e8ec20e026 /vendor/der/src/reader
parentReleasing progress-linux version 1.70.0+dfsg2-1~progress7.99u1. (diff)
downloadrustc-9835e2ae736235810b4ea1c162ca5e65c547e770.tar.xz
rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.zip
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/der/src/reader')
-rw-r--r--vendor/der/src/reader/pem.rs157
-rw-r--r--vendor/der/src/reader/slice.rs8
2 files changed, 144 insertions, 21 deletions
diff --git a/vendor/der/src/reader/pem.rs b/vendor/der/src/reader/pem.rs
index 01bb4f20e..f11341aa6 100644
--- a/vendor/der/src/reader/pem.rs
+++ b/vendor/der/src/reader/pem.rs
@@ -1,16 +1,134 @@
//! Streaming PEM reader.
use super::Reader;
-use crate::{ErrorKind, Header, Length, Result};
-use pem_rfc7468::Decoder;
+use crate::{Decode, Error, ErrorKind, Header, Length, Result};
+use core::cell::RefCell;
+
+#[allow(clippy::integer_arithmetic)]
+mod utils {
+ use crate::{Error, Length, Result};
+ use pem_rfc7468::Decoder;
+
+ #[derive(Clone)]
+ pub(super) struct BufReader<'i> {
+ /// Inner PEM decoder.
+ decoder: Decoder<'i>,
+
+ /// Remaining after base64 decoding
+ remaining: usize,
+
+ /// Read buffer
+ buf: [u8; BufReader::CAPACITY],
+
+ /// Position of the head in the buffer,
+ pos: usize,
+
+ /// Position of the tail in the buffer,
+ cap: usize,
+ }
+
+ impl<'i> BufReader<'i> {
+ const CAPACITY: usize = 256;
+
+ pub fn new(pem: &'i [u8]) -> Result<Self> {
+ let decoder = Decoder::new(pem)?;
+ let remaining = decoder.remaining_len();
+
+ Ok(Self {
+ decoder,
+ remaining,
+ buf: [0u8; 256],
+ pos: 0,
+ cap: 0,
+ })
+ }
+
+ pub fn remaining_len(&self) -> usize {
+ self.decoder.remaining_len() + self.cap - self.pos
+ }
+
+ fn fill_buffer(&mut self) -> Result<()> {
+ debug_assert!(self.pos <= self.cap);
+
+ if self.is_empty() {
+ self.pos = 0;
+ self.cap = 0;
+ }
+
+ let end = (self.cap + self.remaining).min(Self::CAPACITY);
+ let writable_slice = &mut self.buf[self.cap..end];
+ if writable_slice.is_empty() {
+ return Ok(());
+ }
+
+ let wrote = self.decoder.decode(writable_slice)?.len();
+ if wrote == 0 {
+ return Err(Error::incomplete(Length::try_from(self.pos)?));
+ }
+
+ self.cap += wrote;
+ self.remaining -= wrote;
+ debug_assert!(self.cap <= Self::CAPACITY);
+
+ Ok(())
+ }
+
+ /// Get the PEM label which will be used in the encapsulation boundaries
+ /// for this document.
+ pub fn type_label(&self) -> &'i str {
+ self.decoder.type_label()
+ }
+
+ fn is_empty(&self) -> bool {
+ self.pos == self.cap
+ }
+
+ fn as_slice(&self) -> &[u8] {
+ &self.buf[self.pos..self.cap]
+ }
+ }
+
+ impl<'i> BufReader<'i> {
+ pub fn peek_byte(&self) -> Option<u8> {
+ let s = self.as_slice();
+ s.first().copied()
+ }
+
+ pub fn copy_to_slice<'o>(&mut self, buf: &'o mut [u8]) -> Result<&'o [u8]> {
+ let mut output_pos = 0;
+
+ while output_pos < buf.len() {
+ if self.is_empty() {
+ self.fill_buffer()?;
+ }
+
+ let available = &self.buf[self.pos..self.cap];
+ let window_len = (buf.len() - output_pos).min(available.len());
+ let window = &mut buf[output_pos..output_pos + window_len];
+
+ window.copy_from_slice(&available[..window_len]);
+ self.pos += window_len;
+ output_pos += window_len;
+ }
+
+ // Don't leave the read buffer empty for peek_byte()
+ if self.is_empty() && self.decoder.remaining_len() != 0 {
+ self.fill_buffer()?
+ }
+
+ debug_assert_eq!(output_pos, buf.len());
+
+ Ok(buf)
+ }
+ }
+}
/// `Reader` type which decodes PEM on-the-fly.
#[cfg(feature = "pem")]
-#[cfg_attr(docsrs, doc(cfg(feature = "pem")))]
#[derive(Clone)]
pub struct PemReader<'i> {
- /// Inner PEM decoder.
- decoder: Decoder<'i>,
+ /// Inner PEM decoder wrapped in a BufReader.
+ reader: RefCell<utils::BufReader<'i>>,
/// Input length (in bytes after Base64 decoding).
input_len: Length,
@@ -20,17 +138,16 @@ pub struct PemReader<'i> {
}
#[cfg(feature = "pem")]
-#[cfg_attr(docsrs, doc(cfg(feature = "pem")))]
impl<'i> PemReader<'i> {
/// Create a new PEM reader which decodes data on-the-fly.
///
/// Uses the default 64-character line wrapping.
pub fn new(pem: &'i [u8]) -> Result<Self> {
- let decoder = Decoder::new(pem)?;
- let input_len = Length::try_from(decoder.remaining_len())?;
+ let reader = utils::BufReader::new(pem)?;
+ let input_len = Length::try_from(reader.remaining_len())?;
Ok(Self {
- decoder,
+ reader: RefCell::new(reader),
input_len,
position: Length::ZERO,
})
@@ -39,25 +156,30 @@ impl<'i> PemReader<'i> {
/// Get the PEM label which will be used in the encapsulation boundaries
/// for this document.
pub fn type_label(&self) -> &'i str {
- self.decoder.type_label()
+ self.reader.borrow().type_label()
}
}
#[cfg(feature = "pem")]
-#[cfg_attr(docsrs, doc(cfg(feature = "pem")))]
impl<'i> Reader<'i> for PemReader<'i> {
fn input_len(&self) -> Length {
self.input_len
}
fn peek_byte(&self) -> Option<u8> {
- // TODO(tarcieri): lookahead buffer
- None
+ if self.is_finished() {
+ None
+ } else {
+ self.reader.borrow().peek_byte()
+ }
}
fn peek_header(&self) -> Result<Header> {
- // TODO(tarcieri): lookahead buffer
- Err(ErrorKind::Reader.into())
+ if self.is_finished() {
+ Err(Error::incomplete(self.offset()))
+ } else {
+ Header::decode(&mut self.clone())
+ }
}
fn position(&self) -> Length {
@@ -70,12 +192,13 @@ impl<'i> Reader<'i> for PemReader<'i> {
}
fn read_into<'o>(&mut self, buf: &'o mut [u8]) -> Result<&'o [u8]> {
- let bytes = self.decoder.decode(buf)?;
+ let bytes = self.reader.borrow_mut().copy_to_slice(buf)?;
+
self.position = (self.position + bytes.len())?;
debug_assert_eq!(
self.position,
- (self.input_len - Length::try_from(self.decoder.remaining_len())?)?
+ (self.input_len - Length::try_from(self.reader.borrow().remaining_len())?)?
);
Ok(bytes)
diff --git a/vendor/der/src/reader/slice.rs b/vendor/der/src/reader/slice.rs
index 6bab091f3..e78468fed 100644
--- a/vendor/der/src/reader/slice.rs
+++ b/vendor/der/src/reader/slice.rs
@@ -1,12 +1,12 @@
//! Slice reader.
-use crate::{ByteSlice, Decode, Error, ErrorKind, Header, Length, Reader, Result, Tag};
+use crate::{BytesRef, Decode, Error, ErrorKind, Header, Length, Reader, Result, Tag};
/// [`Reader`] which consumes an input byte slice.
#[derive(Clone, Debug)]
pub struct SliceReader<'a> {
/// Byte slice being decoded.
- bytes: ByteSlice<'a>,
+ bytes: BytesRef<'a>,
/// Did the decoding operation fail?
failed: bool,
@@ -19,7 +19,7 @@ impl<'a> SliceReader<'a> {
/// Create a new slice reader for the given byte slice.
pub fn new(bytes: &'a [u8]) -> Result<Self> {
Ok(Self {
- bytes: ByteSlice::new(bytes)?,
+ bytes: BytesRef::new(bytes)?,
failed: false,
position: Length::ZERO,
})
@@ -64,7 +64,7 @@ impl<'a> Reader<'a> for SliceReader<'a> {
fn peek_byte(&self) -> Option<u8> {
self.remaining()
.ok()
- .and_then(|bytes| bytes.get(0).cloned())
+ .and_then(|bytes| bytes.first().cloned())
}
fn peek_header(&self) -> Result<Header> {