/rust/registry/src/index.crates.io-1949cf8c6b5b557f/untrusted-0.7.1/src/untrusted.rs
Line | Count | Source |
1 | | // Copyright 2015-2016 Brian Smith. |
2 | | // |
3 | | // Permission to use, copy, modify, and/or distribute this software for any |
4 | | // purpose with or without fee is hereby granted, provided that the above |
5 | | // copyright notice and this permission notice appear in all copies. |
6 | | // |
7 | | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES |
8 | | // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
9 | | // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR |
10 | | // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
11 | | // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
12 | | // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
13 | | // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
14 | | |
15 | | //! untrusted.rs: Safe, fast, zero-panic, zero-crashing, zero-allocation |
16 | | //! parsing of untrusted inputs in Rust. |
17 | | //! |
18 | | //! <code>git clone https://github.com/briansmith/untrusted</code> |
19 | | //! |
20 | | //! untrusted.rs goes beyond Rust's normal safety guarantees by also |
21 | | //! guaranteeing that parsing will be panic-free, as long as |
22 | | //! `untrusted::Input::as_slice_less_safe()` is not used. It avoids copying |
23 | | //! data and heap allocation and strives to prevent common pitfalls such as |
24 | | //! accidentally parsing input bytes multiple times. In order to meet these |
25 | | //! goals, untrusted.rs is limited in functionality such that it works best for |
26 | | //! input languages with a small fixed amount of lookahead such as ASN.1, TLS, |
27 | | //! TCP/IP, and many other networking, IPC, and related protocols. Languages |
28 | | //! that require more lookahead and/or backtracking require some significant |
29 | | //! contortions to parse using this framework. It would not be realistic to use |
30 | | //! it for parsing programming language code, for example. |
31 | | //! |
32 | | //! The overall pattern for using untrusted.rs is: |
33 | | //! |
34 | | //! 1. Write a recursive-descent-style parser for the input language, where the |
35 | | //! input data is given as a `&mut untrusted::Reader` parameter to each |
36 | | //! function. Each function should have a return type of `Result<V, E>` for |
37 | | //! some value type `V` and some error type `E`, either or both of which may |
38 | | //! be `()`. Functions for parsing the lowest-level language constructs |
39 | | //! should be defined. Those lowest-level functions will parse their inputs |
40 | | //! using `::read_byte()`, `Reader::peek()`, and similar functions. |
41 | | //! Higher-level language constructs are then parsed by calling the |
42 | | //! lower-level functions in sequence. |
43 | | //! |
44 | | //! 2. Wrap the top-most functions of your recursive-descent parser in |
45 | | //! functions that take their input data as an `untrusted::Input`. The |
46 | | //! wrapper functions should call the `Input`'s `read_all` (or a variant |
47 | | //! thereof) method. The wrapper functions are the only ones that should be |
48 | | //! exposed outside the parser's module. |
49 | | //! |
50 | | //! 3. After receiving the input data to parse, wrap it in an `untrusted::Input` |
51 | | //! using `untrusted::Input::from()` as early as possible. Pass the |
52 | | //! `untrusted::Input` to the wrapper functions when they need to be parsed. |
53 | | //! |
54 | | //! In general parsers built using `untrusted::Reader` do not need to explicitly |
55 | | //! check for end-of-input unless they are parsing optional constructs, because |
56 | | //! `Reader::read_byte()` will return `Err(EndOfInput)` on end-of-input. |
57 | | //! Similarly, parsers using `untrusted::Reader` generally don't need to check |
58 | | //! for extra junk at the end of the input as long as the parser's API uses the |
59 | | //! pattern described above, as `read_all` and its variants automatically check |
60 | | //! for trailing junk. `Reader::skip_to_end()` must be used when any remaining |
61 | | //! unread input should be ignored without triggering an error. |
62 | | //! |
63 | | //! untrusted.rs works best when all processing of the input data is done |
64 | | //! through the `untrusted::Input` and `untrusted::Reader` types. In |
65 | | //! particular, avoid trying to parse input data using functions that take |
66 | | //! byte slices. However, when you need to access a part of the input data as |
67 | | //! a slice to use a function that isn't written using untrusted.rs, |
68 | | //! `Input::as_slice_less_safe()` can be used. |
69 | | //! |
70 | | //! It is recommend to use `use untrusted;` and then `untrusted::Input`, |
71 | | //! `untrusted::Reader`, etc., instead of using `use untrusted::*`. Qualifying |
72 | | //! the names with `untrusted` helps remind the reader of the code that it is |
73 | | //! dealing with *untrusted* input. |
74 | | //! |
75 | | //! # Examples |
76 | | //! |
77 | | //! [*ring*](https://github.com/briansmith/ring)'s parser for the subset of |
78 | | //! ASN.1 DER it needs to understand, |
79 | | //! [`ring::der`](https://github.com/briansmith/ring/blob/master/src/der.rs), |
80 | | //! is built on top of untrusted.rs. *ring* also uses untrusted.rs to parse ECC |
81 | | //! public keys, RSA PKCS#1 1.5 padding, and for all other parsing it does. |
82 | | //! |
83 | | //! All of [webpki](https://github.com/briansmith/webpki)'s parsing of X.509 |
84 | | //! certificates (also ASN.1 DER) is done using untrusted.rs. |
85 | | |
86 | | #![doc(html_root_url = "https://briansmith.org/rustdoc/")] |
87 | | // `#[derive(...)]` uses `#[allow(unused_qualifications)]` internally. |
88 | | #![deny(unused_qualifications)] |
89 | | #![forbid( |
90 | | anonymous_parameters, |
91 | | box_pointers, |
92 | | missing_docs, |
93 | | trivial_casts, |
94 | | trivial_numeric_casts, |
95 | | unsafe_code, |
96 | | unstable_features, |
97 | | unused_extern_crates, |
98 | | unused_import_braces, |
99 | | unused_results, |
100 | | variant_size_differences, |
101 | | warnings |
102 | | )] |
103 | | #![no_std] |
104 | | |
105 | | /// A wrapper around `&'a [u8]` that helps in writing panic-free code. |
106 | | /// |
107 | | /// No methods of `Input` will ever panic. |
108 | | #[derive(Clone, Copy, Debug, Eq)] |
109 | | pub struct Input<'a> { |
110 | | value: no_panic::Slice<'a>, |
111 | | } |
112 | | |
113 | | impl<'a> Input<'a> { |
114 | | /// Construct a new `Input` for the given input `bytes`. |
115 | 0 | pub const fn from(bytes: &'a [u8]) -> Self { |
116 | | // This limit is important for avoiding integer overflow. In particular, |
117 | | // `Reader` assumes that an `i + 1 > i` if `input.value.get(i)` does |
118 | | // not return `None`. According to the Rust language reference, the |
119 | | // maximum object size is `core::isize::MAX`, and in practice it is |
120 | | // impossible to create an object of size `core::usize::MAX` or larger. |
121 | 0 | Self { |
122 | 0 | value: no_panic::Slice::new(bytes), |
123 | 0 | } |
124 | 0 | } |
125 | | |
126 | | /// Returns `true` if the input is empty and false otherwise. |
127 | | #[inline] |
128 | 0 | pub fn is_empty(&self) -> bool { self.value.is_empty() } |
129 | | |
130 | | /// Returns the length of the `Input`. |
131 | | #[inline] |
132 | 0 | pub fn len(&self) -> usize { self.value.len() } |
133 | | |
134 | | /// Calls `read` with the given input as a `Reader`, ensuring that `read` |
135 | | /// consumed the entire input. If `read` does not consume the entire input, |
136 | | /// `incomplete_read` is returned. |
137 | 0 | pub fn read_all<F, R, E>(&self, incomplete_read: E, read: F) -> Result<R, E> |
138 | 0 | where |
139 | 0 | F: FnOnce(&mut Reader<'a>) -> Result<R, E>, |
140 | | { |
141 | 0 | let mut input = Reader::new(*self); |
142 | 0 | let result = read(&mut input)?; |
143 | 0 | if input.at_end() { |
144 | 0 | Ok(result) |
145 | | } else { |
146 | 0 | Err(incomplete_read) |
147 | | } |
148 | 0 | } Unexecuted instantiation: <untrusted::Input>::read_all::<aws_lc_rs::io::der::nonnegative_integer::{closure#0}::{closure#0}, (), aws_lc_rs::error::Unspecified>Unexecuted instantiation: <untrusted::Input>::read_all::<aws_lc_rs::io::der::nonnegative_integer::{closure#0}, untrusted::Input, aws_lc_rs::error::Unspecified>Unexecuted instantiation: <untrusted::Input>::read_all::<aws_lc_rs::io::der::bit_string_with_no_unused_bits::{closure#0}, untrusted::Input, aws_lc_rs::error::Unspecified>Unexecuted instantiation: <untrusted::Input>::read_all::<aws_lc_rs::io::der::nonnegative_integer::check_minimum::{closure#0}, (), aws_lc_rs::error::Unspecified>Unexecuted instantiation: <untrusted::Input>::read_all::<_, _, _> |
149 | | |
150 | | /// Access the input as a slice so it can be processed by functions that |
151 | | /// are not written using the Input/Reader framework. |
152 | | #[inline] |
153 | 0 | pub fn as_slice_less_safe(&self) -> &'a [u8] { self.value.as_slice_less_safe() }Unexecuted instantiation: <untrusted::Input>::as_slice_less_safe Unexecuted instantiation: <untrusted::Input>::as_slice_less_safe |
154 | | } |
155 | | |
156 | | impl<'a> From<&'a [u8]> for Input<'a> { |
157 | | #[inline] |
158 | 0 | fn from(value: &'a [u8]) -> Self { Self { value: no_panic::Slice::new(value)} } |
159 | | } |
160 | | |
161 | | // #[derive(PartialEq)] would result in lifetime bounds that are |
162 | | // unnecessarily restrictive; see |
163 | | // https://github.com/rust-lang/rust/issues/26925. |
164 | | impl PartialEq<Input<'_>> for Input<'_> { |
165 | | #[inline] |
166 | 0 | fn eq(&self, other: &Input) -> bool { |
167 | 0 | self.as_slice_less_safe() == other.as_slice_less_safe() |
168 | 0 | } |
169 | | } |
170 | | |
171 | | impl PartialEq<[u8]> for Input<'_> { |
172 | | #[inline] |
173 | 0 | fn eq(&self, other: &[u8]) -> bool { self.as_slice_less_safe() == other } |
174 | | } |
175 | | |
176 | | impl PartialEq<Input<'_>> for [u8] { |
177 | | #[inline] |
178 | 0 | fn eq(&self, other: &Input) -> bool { other.as_slice_less_safe() == self } |
179 | | } |
180 | | |
181 | | /// Calls `read` with the given input as a `Reader`, ensuring that `read` |
182 | | /// consumed the entire input. When `input` is `None`, `read` will be |
183 | | /// called with `None`. |
184 | 0 | pub fn read_all_optional<'a, F, R, E>( |
185 | 0 | input: Option<Input<'a>>, incomplete_read: E, read: F, |
186 | 0 | ) -> Result<R, E> |
187 | 0 | where |
188 | 0 | F: FnOnce(Option<&mut Reader<'a>>) -> Result<R, E>, |
189 | | { |
190 | 0 | match input { |
191 | 0 | Some(input) => { |
192 | 0 | let mut input = Reader::new(input); |
193 | 0 | let result = read(Some(&mut input))?; |
194 | 0 | if input.at_end() { |
195 | 0 | Ok(result) |
196 | | } else { |
197 | 0 | Err(incomplete_read) |
198 | | } |
199 | | }, |
200 | 0 | None => read(None), |
201 | | } |
202 | 0 | } |
203 | | |
204 | | /// A read-only, forward-only* cursor into the data in an `Input`. |
205 | | /// |
206 | | /// Using `Reader` to parse input helps to ensure that no byte of the input |
207 | | /// will be accidentally processed more than once. Using `Reader` in |
208 | | /// conjunction with `read_all` and `read_all_optional` helps ensure that no |
209 | | /// byte of the input is accidentally left unprocessed. The methods of `Reader` |
210 | | /// never panic, so `Reader` also assists the writing of panic-free code. |
211 | | /// |
212 | | /// \* `Reader` is not strictly forward-only because of the method |
213 | | /// `get_input_between_marks`, which is provided mainly to support calculating |
214 | | /// digests over parsed data. |
215 | | #[derive(Debug)] |
216 | | pub struct Reader<'a> { |
217 | | input: no_panic::Slice<'a>, |
218 | | i: usize, |
219 | | } |
220 | | |
221 | | /// An index into the already-parsed input of a `Reader`. |
222 | | pub struct Mark { |
223 | | i: usize, |
224 | | } |
225 | | |
226 | | impl<'a> Reader<'a> { |
227 | | /// Construct a new Reader for the given input. Use `read_all` or |
228 | | /// `read_all_optional` instead of `Reader::new` whenever possible. |
229 | | #[inline] |
230 | 0 | pub fn new(input: Input<'a>) -> Self { |
231 | 0 | Self { |
232 | 0 | input: input.value, |
233 | 0 | i: 0, |
234 | 0 | } |
235 | 0 | } Unexecuted instantiation: <untrusted::Reader>::new Unexecuted instantiation: <untrusted::Reader>::new |
236 | | |
237 | | /// Returns `true` if the reader is at the end of the input, and `false` |
238 | | /// otherwise. |
239 | | #[inline] |
240 | 0 | pub fn at_end(&self) -> bool { self.i == self.input.len() }Unexecuted instantiation: <untrusted::Reader>::at_end Unexecuted instantiation: <untrusted::Reader>::at_end |
241 | | |
242 | | /// Returns an `Input` for already-parsed input that has had its boundaries |
243 | | /// marked using `mark`. |
244 | | #[inline] |
245 | 0 | pub fn get_input_between_marks( |
246 | 0 | &self, mark1: Mark, mark2: Mark, |
247 | 0 | ) -> Result<Input<'a>, EndOfInput> { |
248 | 0 | self.input |
249 | 0 | .subslice(mark1.i..mark2.i) |
250 | 0 | .map(|subslice| Input { value: subslice }) |
251 | 0 | .ok_or(EndOfInput) |
252 | 0 | } |
253 | | |
254 | | /// Return the current position of the `Reader` for future use in a call |
255 | | /// to `get_input_between_marks`. |
256 | | #[inline] |
257 | 0 | pub fn mark(&self) -> Mark { Mark { i: self.i } } |
258 | | |
259 | | /// Returns `true` if there is at least one more byte in the input and that |
260 | | /// byte is equal to `b`, and false otherwise. |
261 | | #[inline] |
262 | 0 | pub fn peek(&self, b: u8) -> bool { |
263 | 0 | match self.input.get(self.i) { |
264 | 0 | Some(actual_b) => b == *actual_b, |
265 | 0 | None => false, |
266 | | } |
267 | 0 | } |
268 | | |
269 | | /// Reads the next input byte. |
270 | | /// |
271 | | /// Returns `Ok(b)` where `b` is the next input byte, or `Err(EndOfInput)` |
272 | | /// if the `Reader` is at the end of the input. |
273 | | #[inline] |
274 | 0 | pub fn read_byte(&mut self) -> Result<u8, EndOfInput> { |
275 | 0 | match self.input.get(self.i) { |
276 | 0 | Some(b) => { |
277 | 0 | self.i += 1; // safe from overflow; see Input::from(). |
278 | 0 | Ok(*b) |
279 | | }, |
280 | 0 | None => Err(EndOfInput), |
281 | | } |
282 | 0 | } Unexecuted instantiation: <untrusted::Reader>::read_byte Unexecuted instantiation: <untrusted::Reader>::read_byte |
283 | | |
284 | | /// Skips `num_bytes` of the input, returning the skipped input as an |
285 | | /// `Input`. |
286 | | /// |
287 | | /// Returns `Ok(i)` if there are at least `num_bytes` of input remaining, |
288 | | /// and `Err(EndOfInput)` otherwise. |
289 | | #[inline] |
290 | 0 | pub fn read_bytes(&mut self, num_bytes: usize) -> Result<Input<'a>, EndOfInput> { |
291 | 0 | let new_i = self.i.checked_add(num_bytes).ok_or(EndOfInput)?; |
292 | 0 | let ret = self |
293 | 0 | .input |
294 | 0 | .subslice(self.i..new_i) |
295 | 0 | .map(|subslice| Input { value: subslice })Unexecuted instantiation: <untrusted::Reader>::read_bytes::{closure#0}Unexecuted instantiation: <untrusted::Reader>::read_bytes::{closure#0} |
296 | 0 | .ok_or(EndOfInput)?; |
297 | 0 | self.i = new_i; |
298 | 0 | Ok(ret) |
299 | 0 | } Unexecuted instantiation: <untrusted::Reader>::read_bytes Unexecuted instantiation: <untrusted::Reader>::read_bytes |
300 | | |
301 | | /// Skips the reader to the end of the input, returning the skipped input |
302 | | /// as an `Input`. |
303 | | #[inline] |
304 | 0 | pub fn read_bytes_to_end(&mut self) -> Input<'a> { |
305 | 0 | let to_skip = self.input.len() - self.i; |
306 | 0 | self.read_bytes(to_skip).unwrap() |
307 | 0 | } Unexecuted instantiation: <untrusted::Reader>::read_bytes_to_end Unexecuted instantiation: <untrusted::Reader>::read_bytes_to_end |
308 | | |
309 | | /// Calls `read()` with the given input as a `Reader`. On success, returns a |
310 | | /// pair `(bytes_read, r)` where `bytes_read` is what `read()` consumed and |
311 | | /// `r` is `read()`'s return value. |
312 | 0 | pub fn read_partial<F, R, E>(&mut self, read: F) -> Result<(Input<'a>, R), E> |
313 | 0 | where |
314 | 0 | F: FnOnce(&mut Reader<'a>) -> Result<R, E>, |
315 | | { |
316 | 0 | let start = self.i; |
317 | 0 | let r = read(self)?; |
318 | 0 | let bytes_read = Input { |
319 | 0 | value: self.input.subslice(start..self.i).unwrap() |
320 | 0 | }; |
321 | 0 | Ok((bytes_read, r)) |
322 | 0 | } |
323 | | |
324 | | /// Skips `num_bytes` of the input. |
325 | | /// |
326 | | /// Returns `Ok(i)` if there are at least `num_bytes` of input remaining, |
327 | | /// and `Err(EndOfInput)` otherwise. |
328 | | #[inline] |
329 | 0 | pub fn skip(&mut self, num_bytes: usize) -> Result<(), EndOfInput> { |
330 | 0 | self.read_bytes(num_bytes).map(|_| ()) |
331 | 0 | } |
332 | | |
333 | | /// Skips the reader to the end of the input. |
334 | | #[inline] |
335 | 0 | pub fn skip_to_end(&mut self) -> () { let _ = self.read_bytes_to_end(); } |
336 | | } |
337 | | |
338 | | /// The error type used to indicate the end of the input was reached before the |
339 | | /// operation could be completed. |
340 | | #[derive(Clone, Copy, Debug, Eq, PartialEq)] |
341 | | pub struct EndOfInput; |
342 | | |
343 | | mod no_panic { |
344 | | use core; |
345 | | |
346 | | /// A wrapper around a slice that exposes no functions that can panic. |
347 | | #[derive(Clone, Copy, Debug, Eq, PartialEq)] |
348 | | pub struct Slice<'a> { |
349 | | bytes: &'a [u8], |
350 | | } |
351 | | |
352 | | impl<'a> Slice<'a> { |
353 | | #[inline] |
354 | 0 | pub const fn new(bytes: &'a [u8]) -> Self { Self { bytes } } |
355 | | |
356 | | #[inline] |
357 | 0 | pub fn get(&self, i: usize) -> Option<&u8> { self.bytes.get(i) }Unexecuted instantiation: <untrusted::no_panic::Slice>::get Unexecuted instantiation: <untrusted::no_panic::Slice>::get |
358 | | |
359 | | #[inline] |
360 | 0 | pub fn subslice(&self, r: core::ops::Range<usize>) -> Option<Self> { |
361 | 0 | self.bytes.get(r).map(|bytes| Self { bytes })Unexecuted instantiation: <untrusted::no_panic::Slice>::subslice::{closure#0}Unexecuted instantiation: <untrusted::no_panic::Slice>::subslice::{closure#0} |
362 | 0 | } Unexecuted instantiation: <untrusted::no_panic::Slice>::subslice Unexecuted instantiation: <untrusted::no_panic::Slice>::subslice |
363 | | |
364 | | #[inline] |
365 | 0 | pub fn is_empty(&self) -> bool { self.bytes.is_empty() } |
366 | | |
367 | | #[inline] |
368 | 0 | pub fn len(&self) -> usize { self.bytes.len() }Unexecuted instantiation: <untrusted::no_panic::Slice>::len Unexecuted instantiation: <untrusted::no_panic::Slice>::len |
369 | | |
370 | | #[inline] |
371 | 0 | pub fn as_slice_less_safe(&self) -> &'a [u8] { self.bytes }Unexecuted instantiation: <untrusted::no_panic::Slice>::as_slice_less_safe Unexecuted instantiation: <untrusted::no_panic::Slice>::as_slice_less_safe |
372 | | } |
373 | | |
374 | | } // mod no_panic |