Skip to content

Commit b45caa8

Browse files
authored
der: have SliceReader use reader::position::Position (#2378)
The `Position` struct was extracted in #1880 but never actually wired up so `SliceReader` can use it to share logic with `PemReader`, which this PR implements.
1 parent 42b4325 commit b45caa8

3 files changed

Lines changed: 47 additions & 58 deletions

File tree

der/src/reader.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
pub(crate) mod pem;
55
pub(crate) mod slice;
66

7-
#[cfg(feature = "pem")]
87
mod position;
98

109
use crate::{

der/src/reader/position.rs

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,9 @@ impl Position {
2121
}
2222
}
2323

24-
/// Get the input length.
25-
pub(super) fn input_len(&self) -> Length {
26-
self.input_len
27-
}
28-
29-
/// Get the current position.
30-
pub(super) fn current(&self) -> Length {
31-
self.position
32-
}
33-
3424
/// Advance the current position by the given amount.
3525
///
36-
/// # Returns
37-
///
38-
/// The new current position.
26+
/// Returns the new current position.
3927
pub(super) fn advance(&mut self, amount: Length) -> Result<Length> {
4028
let new_position = (self.position + amount)?;
4129

@@ -51,6 +39,22 @@ impl Position {
5139
Ok(new_position)
5240
}
5341

42+
/// Get the current position.
43+
pub(super) fn current(&self) -> Length {
44+
self.position
45+
}
46+
47+
/// Get the input length.
48+
pub(super) fn input_len(&self) -> Length {
49+
self.input_len
50+
}
51+
52+
/// Get the remaining length.
53+
pub(super) fn remaining_len(&self) -> Length {
54+
debug_assert!(self.position <= self.input_len());
55+
self.input_len.saturating_sub(self.position)
56+
}
57+
5458
/// Split a nested position tracker of the given size.
5559
///
5660
/// # Returns

der/src/reader/slice.rs

Lines changed: 30 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! Slice reader.
22
3+
use super::position::Position;
34
use crate::{BytesRef, Decode, EncodingRules, Error, ErrorKind, Length, Reader};
45

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

1718
/// Position within the decoded slice.
18-
position: Length,
19+
position: Position,
1920
}
2021

2122
impl<'a> SliceReader<'a> {
@@ -39,15 +40,15 @@ impl<'a> SliceReader<'a> {
3940
bytes: BytesRef::new(bytes)?,
4041
encoding_rules,
4142
failed: false,
42-
position: Length::ZERO,
43+
position: Position::new(bytes.len().try_into()?),
4344
})
4445
}
4546

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

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

59-
/// Obtain the remaining bytes in this slice reader from the current cursor
60-
/// position.
60+
/// Obtain the remaining bytes in this slice reader from the current cursor position.
6161
pub(crate) fn remaining(&self) -> Result<&'a [u8], Error> {
6262
if self.is_failed() {
63-
Err(ErrorKind::Failed.at(self.position))
63+
Err(ErrorKind::Failed.at(self.position.current()))
6464
} else {
6565
self.bytes
6666
.as_slice()
67-
.get(self.position.try_into()?..)
67+
.get(self.position.current().try_into()?..)
6868
.ok_or_else(|| Error::incomplete(self.input_len()))
6969
}
7070
}
71-
/// Creates new [`SliceReader`] without advancing current reader.
72-
pub(crate) fn new_nested_reader(&mut self, len: Length) -> Result<Self, Error> {
73-
let prefix_len = (self.position + len)?;
74-
let mut nested_reader = self.clone();
75-
nested_reader.bytes = self.bytes.prefix(prefix_len)?;
76-
Ok(nested_reader)
77-
}
7871
}
7972

8073
impl<'a> Reader<'a> for SliceReader<'a> {
@@ -89,29 +82,26 @@ impl<'a> Reader<'a> for SliceReader<'a> {
8982
}
9083

9184
fn position(&self) -> Length {
92-
self.position
85+
self.position.current()
9386
}
9487

9588
/// Read nested data of the given length.
89+
#[inline]
9690
fn read_nested<T, F, E>(&mut self, len: Length, f: F) -> Result<T, E>
9791
where
9892
F: FnOnce(&mut Self) -> Result<T, E>,
9993
E: From<Error>,
10094
{
101-
let mut nested_reader = self.new_nested_reader(len)?;
102-
let ret = f(&mut nested_reader);
103-
self.position = nested_reader.position;
104-
self.failed = nested_reader.failed;
105-
106-
match ret {
107-
Ok(value) => {
108-
nested_reader.finish().inspect_err(|_e| {
109-
self.failed = true;
110-
})?;
111-
Ok(value)
112-
}
113-
Err(err) => Err(err),
114-
}
95+
// Slice `self.bytes` as a secondary check we don't read past end-of-slice
96+
let bytes = self.bytes;
97+
let prefix_len = (self.position.current() + len)?;
98+
self.bytes = self.bytes.prefix(prefix_len)?;
99+
100+
let resumption = self.position.split_nested(len)?;
101+
let ret = f(self);
102+
self.bytes = bytes;
103+
self.position.resume_nested(resumption);
104+
ret
115105
}
116106

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

122112
match self.remaining()?.get(..len.try_into()?) {
123113
Some(result) => {
124-
self.position = (self.position + len)?;
114+
self.position.advance(len)?;
125115
Ok(result)
126116
}
127117
None => Err(self.error(ErrorKind::Incomplete {
128-
expected_len: (self.position + len)?,
118+
expected_len: (self.position.current() + len)?,
129119
actual_len: self.input_len(),
130120
})),
131121
}
@@ -142,27 +132,23 @@ impl<'a> Reader<'a> for SliceReader<'a> {
142132
}
143133

144134
fn error(&mut self, kind: ErrorKind) -> Error {
145-
self.failed = true;
146-
kind.at(self.position)
135+
self.error(kind)
147136
}
148137

149-
fn finish(self) -> Result<(), Error> {
138+
fn finish(mut self) -> Result<(), Error> {
150139
if self.is_failed() {
151-
Err(ErrorKind::Failed.at(self.position))
140+
Err(ErrorKind::Failed.at(self.position.current()))
152141
} else if !self.is_finished() {
153-
Err(ErrorKind::TrailingData {
154-
decoded: self.position,
155-
remaining: self.remaining_len(),
156-
}
157-
.at(self.position))
142+
let decoded = self.position.current();
143+
let remaining = self.remaining_len();
144+
Err(self.error(ErrorKind::TrailingData { decoded, remaining }))
158145
} else {
159146
Ok(())
160147
}
161148
}
162149

163150
fn remaining_len(&self) -> Length {
164-
debug_assert!(self.position <= self.input_len());
165-
self.input_len().saturating_sub(self.position)
151+
self.position.remaining_len()
166152
}
167153
}
168154

0 commit comments

Comments
 (0)