/rust/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.10/src/reader/slice.rs
Line | Count | Source (jump to first uncovered line) |
1 | | //! Slice reader. |
2 | | |
3 | | use crate::{BytesRef, Decode, Error, ErrorKind, Header, Length, Reader, Result, Tag}; |
4 | | |
5 | | /// [`Reader`] which consumes an input byte slice. |
6 | | #[derive(Clone, Debug)] |
7 | | pub struct SliceReader<'a> { |
8 | | /// Byte slice being decoded. |
9 | | bytes: BytesRef<'a>, |
10 | | |
11 | | /// Did the decoding operation fail? |
12 | | failed: bool, |
13 | | |
14 | | /// Position within the decoded slice. |
15 | | position: Length, |
16 | | } |
17 | | |
18 | | impl<'a> SliceReader<'a> { |
19 | | /// Create a new slice reader for the given byte slice. |
20 | 3.09k | pub fn new(bytes: &'a [u8]) -> Result<Self> { |
21 | 3.09k | Ok(Self { |
22 | 3.09k | bytes: BytesRef::new(bytes)?, |
23 | | failed: false, |
24 | | position: Length::ZERO, |
25 | | }) |
26 | 3.09k | } |
27 | | |
28 | | /// Return an error with the given [`ErrorKind`], annotating it with |
29 | | /// context about where the error occurred. |
30 | 0 | pub fn error(&mut self, kind: ErrorKind) -> Error { |
31 | 0 | self.failed = true; |
32 | 0 | kind.at(self.position) |
33 | 0 | } |
34 | | |
35 | | /// Return an error for an invalid value with the given tag. |
36 | 0 | pub fn value_error(&mut self, tag: Tag) -> Error { |
37 | 0 | self.error(tag.value_error().kind()) |
38 | 0 | } |
39 | | |
40 | | /// Did the decoding operation fail due to an error? |
41 | 52.6k | pub fn is_failed(&self) -> bool { |
42 | 52.6k | self.failed |
43 | 52.6k | } |
44 | | |
45 | | /// Obtain the remaining bytes in this slice reader from the current cursor |
46 | | /// position. |
47 | 24.7k | fn remaining(&self) -> Result<&'a [u8]> { |
48 | 24.7k | if self.is_failed() { |
49 | 0 | Err(ErrorKind::Failed.at(self.position)) |
50 | | } else { |
51 | 24.7k | self.bytes |
52 | 24.7k | .as_slice() |
53 | 24.7k | .get(self.position.try_into()?..) |
54 | 24.7k | .ok_or_else(|| Error::incomplete(self.input_len())) |
55 | | } |
56 | 24.7k | } |
57 | | } |
58 | | |
59 | | impl<'a> Reader<'a> for SliceReader<'a> { |
60 | 6.19k | fn input_len(&self) -> Length { |
61 | 6.19k | self.bytes.len() |
62 | 6.19k | } |
63 | | |
64 | 0 | fn peek_byte(&self) -> Option<u8> { |
65 | 0 | self.remaining() |
66 | 0 | .ok() |
67 | 0 | .and_then(|bytes| bytes.first().cloned()) |
68 | 0 | } |
69 | | |
70 | 0 | fn peek_header(&self) -> Result<Header> { |
71 | 0 | Header::decode(&mut self.clone()) |
72 | 0 | } |
73 | | |
74 | 0 | fn position(&self) -> Length { |
75 | 0 | self.position |
76 | 0 | } |
77 | | |
78 | 24.7k | fn read_slice(&mut self, len: Length) -> Result<&'a [u8]> { |
79 | 24.7k | if self.is_failed() { |
80 | 0 | return Err(self.error(ErrorKind::Failed)); |
81 | 24.7k | } |
82 | 24.7k | |
83 | 24.7k | match self.remaining()?.get(..len.try_into()?) { |
84 | 24.7k | Some(result) => { |
85 | 24.7k | self.position = (self.position + len)?; |
86 | 24.7k | Ok(result) |
87 | | } |
88 | 0 | None => Err(self.error(ErrorKind::Incomplete { |
89 | 0 | expected_len: (self.position + len)?, |
90 | 0 | actual_len: self.input_len(), |
91 | | })), |
92 | | } |
93 | 24.7k | } |
94 | | |
95 | 0 | fn decode<T: Decode<'a>>(&mut self) -> Result<T> { |
96 | 0 | if self.is_failed() { |
97 | 0 | return Err(self.error(ErrorKind::Failed)); |
98 | 0 | } |
99 | 0 |
|
100 | 0 | T::decode(self).map_err(|e| { |
101 | 0 | self.failed = true; |
102 | 0 | e.nested(self.position) |
103 | 0 | }) |
104 | 0 | } |
105 | | |
106 | 0 | fn error(&mut self, kind: ErrorKind) -> Error { |
107 | 0 | self.failed = true; |
108 | 0 | kind.at(self.position) |
109 | 0 | } |
110 | | |
111 | 3.09k | fn finish<T>(self, value: T) -> Result<T> { |
112 | 3.09k | if self.is_failed() { |
113 | 0 | Err(ErrorKind::Failed.at(self.position)) |
114 | 3.09k | } else if !self.is_finished() { |
115 | 0 | Err(ErrorKind::TrailingData { |
116 | 0 | decoded: self.position, |
117 | 0 | remaining: self.remaining_len(), |
118 | 0 | } |
119 | 0 | .at(self.position)) |
120 | | } else { |
121 | 3.09k | Ok(value) |
122 | | } |
123 | 3.09k | } <der::reader::slice::SliceReader as der::reader::Reader>::finish::<(der::asn1::integer::uint::UintRef, der::asn1::integer::uint::UintRef)> Line | Count | Source | 111 | 3.09k | fn finish<T>(self, value: T) -> Result<T> { | 112 | 3.09k | if self.is_failed() { | 113 | 0 | Err(ErrorKind::Failed.at(self.position)) | 114 | 3.09k | } else if !self.is_finished() { | 115 | 0 | Err(ErrorKind::TrailingData { | 116 | 0 | decoded: self.position, | 117 | 0 | remaining: self.remaining_len(), | 118 | 0 | } | 119 | 0 | .at(self.position)) | 120 | | } else { | 121 | 3.09k | Ok(value) | 122 | | } | 123 | 3.09k | } |
Unexecuted instantiation: <der::reader::slice::SliceReader as der::reader::Reader>::finish::<sec1::private_key::EcPrivateKey> Unexecuted instantiation: <der::reader::slice::SliceReader as der::reader::Reader>::finish::<der::document::Document> Unexecuted instantiation: <der::reader::slice::SliceReader as der::reader::Reader>::finish::<der::asn1::bit_string::BitStringRef> Unexecuted instantiation: <der::reader::slice::SliceReader as der::reader::Reader>::finish::<der::asn1::ia5_string::Ia5StringRef> Unexecuted instantiation: <der::reader::slice::SliceReader as der::reader::Reader>::finish::<der::asn1::utf8_string::Utf8StringRef> Unexecuted instantiation: <der::reader::slice::SliceReader as der::reader::Reader>::finish::<der::asn1::octet_string::OctetStringRef> Unexecuted instantiation: <der::reader::slice::SliceReader as der::reader::Reader>::finish::<der::asn1::teletex_string::TeletexStringRef> Unexecuted instantiation: <der::reader::slice::SliceReader as der::reader::Reader>::finish::<der::asn1::videotex_string::VideotexStringRef> Unexecuted instantiation: <der::reader::slice::SliceReader as der::reader::Reader>::finish::<der::asn1::generalized_time::GeneralizedTime> Unexecuted instantiation: <der::reader::slice::SliceReader as der::reader::Reader>::finish::<der::asn1::printable_string::PrintableStringRef> Unexecuted instantiation: <der::reader::slice::SliceReader as der::reader::Reader>::finish::<der::asn1::any::AnyRef> Unexecuted instantiation: <der::reader::slice::SliceReader as der::reader::Reader>::finish::<der::asn1::null::Null> Unexecuted instantiation: <der::reader::slice::SliceReader as der::reader::Reader>::finish::<der::asn1::utc_time::UtcTime> Unexecuted instantiation: <der::reader::slice::SliceReader as der::reader::Reader>::finish::<der::asn1::bit_string::allocating::BitString> Unexecuted instantiation: <der::reader::slice::SliceReader as der::reader::Reader>::finish::<der::asn1::ia5_string::allocation::Ia5String> Unexecuted instantiation: <der::reader::slice::SliceReader as der::reader::Reader>::finish::<der::asn1::octet_string::allocating::OctetString> Unexecuted instantiation: <der::reader::slice::SliceReader as der::reader::Reader>::finish::<der::asn1::teletex_string::allocation::TeletexString> Unexecuted instantiation: <der::reader::slice::SliceReader as der::reader::Reader>::finish::<der::asn1::printable_string::allocation::PrintableString> Unexecuted instantiation: <der::reader::slice::SliceReader as der::reader::Reader>::finish::<der::asn1::integer::int::IntRef> Unexecuted instantiation: <der::reader::slice::SliceReader as der::reader::Reader>::finish::<der::asn1::integer::uint::UintRef> Unexecuted instantiation: <der::reader::slice::SliceReader as der::reader::Reader>::finish::<der::asn1::integer::int::allocating::Int> Unexecuted instantiation: <der::reader::slice::SliceReader as der::reader::Reader>::finish::<der::asn1::integer::uint::allocating::Uint> Unexecuted instantiation: <der::reader::slice::SliceReader as der::reader::Reader>::finish::<i8> Unexecuted instantiation: <der::reader::slice::SliceReader as der::reader::Reader>::finish::<u8> Unexecuted instantiation: <der::reader::slice::SliceReader as der::reader::Reader>::finish::<i32> Unexecuted instantiation: <der::reader::slice::SliceReader as der::reader::Reader>::finish::<u32> Unexecuted instantiation: <der::reader::slice::SliceReader as der::reader::Reader>::finish::<i128> Unexecuted instantiation: <der::reader::slice::SliceReader as der::reader::Reader>::finish::<u128> Unexecuted instantiation: <der::reader::slice::SliceReader as der::reader::Reader>::finish::<i16> Unexecuted instantiation: <der::reader::slice::SliceReader as der::reader::Reader>::finish::<u16> Unexecuted instantiation: <der::reader::slice::SliceReader as der::reader::Reader>::finish::<()> Unexecuted instantiation: <der::reader::slice::SliceReader as der::reader::Reader>::finish::<i64> Unexecuted instantiation: <der::reader::slice::SliceReader as der::reader::Reader>::finish::<u64> |
124 | | |
125 | 6.19k | fn remaining_len(&self) -> Length { |
126 | 6.19k | debug_assert!(self.position <= self.input_len()); |
127 | 6.19k | self.input_len().saturating_sub(self.position) |
128 | 6.19k | } |
129 | | } |
130 | | |
131 | | #[cfg(test)] |
132 | | mod tests { |
133 | | use super::SliceReader; |
134 | | use crate::{Decode, ErrorKind, Length, Reader, Tag}; |
135 | | use hex_literal::hex; |
136 | | |
137 | | // INTEGER: 42 |
138 | | const EXAMPLE_MSG: &[u8] = &hex!("02012A00"); |
139 | | |
140 | | #[test] |
141 | | fn empty_message() { |
142 | | let mut reader = SliceReader::new(&[]).unwrap(); |
143 | | let err = bool::decode(&mut reader).err().unwrap(); |
144 | | assert_eq!(Some(Length::ZERO), err.position()); |
145 | | |
146 | | match err.kind() { |
147 | | ErrorKind::Incomplete { |
148 | | expected_len, |
149 | | actual_len, |
150 | | } => { |
151 | | assert_eq!(actual_len, 0u8.into()); |
152 | | assert_eq!(expected_len, 1u8.into()); |
153 | | } |
154 | | other => panic!("unexpected error kind: {:?}", other), |
155 | | } |
156 | | } |
157 | | |
158 | | #[test] |
159 | | fn invalid_field_length() { |
160 | | const MSG_LEN: usize = 2; |
161 | | |
162 | | let mut reader = SliceReader::new(&EXAMPLE_MSG[..MSG_LEN]).unwrap(); |
163 | | let err = i8::decode(&mut reader).err().unwrap(); |
164 | | assert_eq!(Some(Length::from(2u8)), err.position()); |
165 | | |
166 | | match err.kind() { |
167 | | ErrorKind::Incomplete { |
168 | | expected_len, |
169 | | actual_len, |
170 | | } => { |
171 | | assert_eq!(actual_len, MSG_LEN.try_into().unwrap()); |
172 | | assert_eq!(expected_len, (MSG_LEN + 1).try_into().unwrap()); |
173 | | } |
174 | | other => panic!("unexpected error kind: {:?}", other), |
175 | | } |
176 | | } |
177 | | |
178 | | #[test] |
179 | | fn trailing_data() { |
180 | | let mut reader = SliceReader::new(EXAMPLE_MSG).unwrap(); |
181 | | let x = i8::decode(&mut reader).unwrap(); |
182 | | assert_eq!(42i8, x); |
183 | | |
184 | | let err = reader.finish(x).err().unwrap(); |
185 | | assert_eq!(Some(Length::from(3u8)), err.position()); |
186 | | |
187 | | assert_eq!( |
188 | | ErrorKind::TrailingData { |
189 | | decoded: 3u8.into(), |
190 | | remaining: 1u8.into() |
191 | | }, |
192 | | err.kind() |
193 | | ); |
194 | | } |
195 | | |
196 | | #[test] |
197 | | fn peek_tag() { |
198 | | let reader = SliceReader::new(EXAMPLE_MSG).unwrap(); |
199 | | assert_eq!(reader.position(), Length::ZERO); |
200 | | assert_eq!(reader.peek_tag().unwrap(), Tag::Integer); |
201 | | assert_eq!(reader.position(), Length::ZERO); // Position unchanged |
202 | | } |
203 | | |
204 | | #[test] |
205 | | fn peek_header() { |
206 | | let reader = SliceReader::new(EXAMPLE_MSG).unwrap(); |
207 | | assert_eq!(reader.position(), Length::ZERO); |
208 | | |
209 | | let header = reader.peek_header().unwrap(); |
210 | | assert_eq!(header.tag, Tag::Integer); |
211 | | assert_eq!(header.length, Length::ONE); |
212 | | assert_eq!(reader.position(), Length::ZERO); // Position unchanged |
213 | | } |
214 | | } |