Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion der/src/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
pub(crate) mod pem;
pub(crate) mod slice;

#[cfg(feature = "pem")]
mod position;

use crate::{
Expand Down
30 changes: 17 additions & 13 deletions der/src/reader/position.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,9 @@ impl Position {
}
}

/// Get the input length.
pub(super) fn input_len(&self) -> Length {
self.input_len
}

/// Get the current position.
pub(super) fn current(&self) -> Length {
self.position
}

/// Advance the current position by the given amount.
///
/// # Returns
///
/// The new current position.
/// Returns the new current position.
pub(super) fn advance(&mut self, amount: Length) -> Result<Length> {
let new_position = (self.position + amount)?;

Expand All @@ -51,6 +39,22 @@ impl Position {
Ok(new_position)
}

/// Get the current position.
pub(super) fn current(&self) -> Length {
self.position
}

/// Get the input length.
pub(super) fn input_len(&self) -> Length {
self.input_len
}

/// Get the remaining length.
pub(super) fn remaining_len(&self) -> Length {
debug_assert!(self.position <= self.input_len());
self.input_len.saturating_sub(self.position)
}

/// Split a nested position tracker of the given size.
///
/// # Returns
Expand Down
74 changes: 30 additions & 44 deletions der/src/reader/slice.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Slice reader.

use super::position::Position;
use crate::{BytesRef, Decode, EncodingRules, Error, ErrorKind, Length, Reader};

/// [`Reader`] which consumes an input byte slice.
Expand All @@ -15,7 +16,7 @@ pub struct SliceReader<'a> {
failed: bool,

/// Position within the decoded slice.
position: Length,
position: Position,
}

impl<'a> SliceReader<'a> {
Expand All @@ -39,15 +40,15 @@ impl<'a> SliceReader<'a> {
bytes: BytesRef::new(bytes)?,
encoding_rules,
failed: false,
position: Length::ZERO,
position: Position::new(bytes.len().try_into()?),
})
}

/// Return an error with the given [`ErrorKind`], annotating it with
/// context about where the error occurred.
/// Return an error with the given [`ErrorKind`], annotating it with context about where the
/// error occurred.
pub fn error(&mut self, kind: ErrorKind) -> Error {
self.failed = true;
kind.at(self.position)
kind.at(self.position.current())
}

/// Did the decoding operation fail due to an error?
Expand All @@ -56,25 +57,17 @@ impl<'a> SliceReader<'a> {
self.failed
}

/// Obtain the remaining bytes in this slice reader from the current cursor
/// position.
/// Obtain the remaining bytes in this slice reader from the current cursor position.
pub(crate) fn remaining(&self) -> Result<&'a [u8], Error> {
if self.is_failed() {
Err(ErrorKind::Failed.at(self.position))
Err(ErrorKind::Failed.at(self.position.current()))
} else {
self.bytes
.as_slice()
.get(self.position.try_into()?..)
.get(self.position.current().try_into()?..)
.ok_or_else(|| Error::incomplete(self.input_len()))
}
}
/// Creates new [`SliceReader`] without advancing current reader.
pub(crate) fn new_nested_reader(&mut self, len: Length) -> Result<Self, Error> {
let prefix_len = (self.position + len)?;
let mut nested_reader = self.clone();
nested_reader.bytes = self.bytes.prefix(prefix_len)?;
Ok(nested_reader)
}
}

impl<'a> Reader<'a> for SliceReader<'a> {
Expand All @@ -89,29 +82,26 @@ impl<'a> Reader<'a> for SliceReader<'a> {
}

fn position(&self) -> Length {
self.position
self.position.current()
}

/// Read nested data of the given length.
#[inline]
fn read_nested<T, F, E>(&mut self, len: Length, f: F) -> Result<T, E>
where
F: FnOnce(&mut Self) -> Result<T, E>,
E: From<Error>,
{
let mut nested_reader = self.new_nested_reader(len)?;
let ret = f(&mut nested_reader);
self.position = nested_reader.position;
self.failed = nested_reader.failed;

match ret {
Ok(value) => {
nested_reader.finish().inspect_err(|_e| {
self.failed = true;
})?;
Ok(value)
}
Err(err) => Err(err),
}
// Slice `self.bytes` as a secondary check we don't read past end-of-slice
let bytes = self.bytes;
let prefix_len = (self.position.current() + len)?;
self.bytes = self.bytes.prefix(prefix_len)?;

let resumption = self.position.split_nested(len)?;
let ret = f(self);
self.bytes = bytes;
self.position.resume_nested(resumption);
ret
}

fn read_slice(&mut self, len: Length) -> Result<&'a [u8], Error> {
Expand All @@ -121,11 +111,11 @@ impl<'a> Reader<'a> for SliceReader<'a> {

match self.remaining()?.get(..len.try_into()?) {
Some(result) => {
self.position = (self.position + len)?;
self.position.advance(len)?;
Ok(result)
}
None => Err(self.error(ErrorKind::Incomplete {
expected_len: (self.position + len)?,
expected_len: (self.position.current() + len)?,
actual_len: self.input_len(),
})),
}
Expand All @@ -142,27 +132,23 @@ impl<'a> Reader<'a> for SliceReader<'a> {
}

fn error(&mut self, kind: ErrorKind) -> Error {
self.failed = true;
kind.at(self.position)
self.error(kind)
}

fn finish(self) -> Result<(), Error> {
fn finish(mut self) -> Result<(), Error> {
if self.is_failed() {
Err(ErrorKind::Failed.at(self.position))
Err(ErrorKind::Failed.at(self.position.current()))
} else if !self.is_finished() {
Err(ErrorKind::TrailingData {
decoded: self.position,
remaining: self.remaining_len(),
}
.at(self.position))
let decoded = self.position.current();
let remaining = self.remaining_len();
Err(self.error(ErrorKind::TrailingData { decoded, remaining }))
} else {
Ok(())
}
}

fn remaining_len(&self) -> Length {
debug_assert!(self.position <= self.input_len());
self.input_len().saturating_sub(self.position)
self.position.remaining_len()
}
}

Expand Down
Loading