RPM build fix (reverted CI changes which will need to be un-reverted or made conditional) and vendor Rust dependencies to make builds much faster in any CI system.
This commit is contained in:
1
zeroidc/vendor/untrusted/.cargo-checksum.json
vendored
Normal file
1
zeroidc/vendor/untrusted/.cargo-checksum.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"files":{"Cargo.toml":"59bb105a246b4729fc4bd17a4c3d6a86baa93ff912d29832afeb1bbc4668ea82","LICENSE.txt":"7abd9b6960dcf7d4d0a48606a5b71bfe37d472db68d70637f3a58a56785f1621","README.md":"8ec7954c78b7bceecc1757f2af855045969c3197ad306c9a5d3a6e0c43a8a9cd","rustfmt.toml":"35224a8b085bf87a77b0c6ab0c58f5deae37d1bddfbf59df98f9155a796ab3a7","src/untrusted.rs":"0be77ed2066283297671ec1f9e7c0003a37364d40f9853d2cb1a0139edd0de1a","tests/tests.rs":"7ea1550681e427fa6bf88ba41b13ebd810afd46c50fca85b297cd4e6d9a02157"},"package":"a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"}
|
||||
29
zeroidc/vendor/untrusted/Cargo.toml
vendored
Normal file
29
zeroidc/vendor/untrusted/Cargo.toml
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
|
||||
#
|
||||
# When uploading crates to the registry Cargo will automatically
|
||||
# "normalize" Cargo.toml files for maximal compatibility
|
||||
# with all versions of Cargo and also rewrite `path` dependencies
|
||||
# to registry (e.g., crates.io) dependencies
|
||||
#
|
||||
# If you believe there's an error in this file please file an
|
||||
# issue against the rust-lang/cargo repository. If you're
|
||||
# editing this file be aware that the upstream Cargo.toml
|
||||
# will likely look very different (and much more reasonable)
|
||||
|
||||
[package]
|
||||
edition = "2018"
|
||||
name = "untrusted"
|
||||
version = "0.7.1"
|
||||
authors = ["Brian Smith <brian@briansmith.org>"]
|
||||
description = "Safe, fast, zero-panic, zero-crashing, zero-allocation parsing of untrusted inputs in Rust."
|
||||
documentation = "https://briansmith.org/rustdoc/untrusted/"
|
||||
readme = "README.md"
|
||||
license = "ISC"
|
||||
repository = "https://github.com/briansmith/untrusted"
|
||||
[profile.bench]
|
||||
opt-level = 2
|
||||
lto = true
|
||||
|
||||
[lib]
|
||||
name = "untrusted"
|
||||
path = "src/untrusted.rs"
|
||||
13
zeroidc/vendor/untrusted/LICENSE.txt
vendored
Normal file
13
zeroidc/vendor/untrusted/LICENSE.txt
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
// Copyright 2015-2016 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
109
zeroidc/vendor/untrusted/README.md
vendored
Normal file
109
zeroidc/vendor/untrusted/README.md
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
|
||||
|
||||
untrusted.rs
|
||||
============
|
||||
|
||||
Safe, fast, zero-panic, zero-crashing, zero-allocation parsing of untrusted
|
||||
inputs in Rust.
|
||||
|
||||
untrusted.rs is 100% Rust with no use of `unsafe`. It never uses the heap.
|
||||
No part of untrusted.rs's API will ever panic or cause a crash. It is
|
||||
`#![no_std]` and so it works perfectly with both libcore- and libstd- based
|
||||
projects. It does not depend on any crates other than libcore.
|
||||
|
||||
untrusted.rs is intended to be used with the latest version of Rust Stable.
|
||||
It should usually work with the latest Rust Beta and Rust Nightly versions
|
||||
too. Using a version of untrusted.rs other than the latest release available
|
||||
on crates.io is not recommended.
|
||||
|
||||
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
See the documentation at
|
||||
https://briansmith.org/rustdoc/untrusted/.
|
||||
|
||||
To use untrusted.rs in your project, add a dependency to your
|
||||
Cargo.toml like this:
|
||||
|
||||
```
|
||||
[dependencies]
|
||||
untrusted = "0.2"
|
||||
```
|
||||
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
[*ring*](https://github.com/briansmith/ring)'s parser for the subset of ASN.1
|
||||
DER it needs to understand,
|
||||
[`ring::der`](https://github.com/briansmith/ring/blob/master/src/der.rs), is
|
||||
built on top of untrusted.rs. *ring* also uses untrusted.rs to parse ECC public
|
||||
keys, RSA PKCS#1 1.5 padding, and everything else.
|
||||
|
||||
All of [webpki](https://github.com/briansmith/webpki)'s parsing of X.509
|
||||
certificates (also ASN.1 DER) is done using untrusted.rs.
|
||||
|
||||
|
||||
|
||||
Contributing
|
||||
------------
|
||||
|
||||
Patches welcome!
|
||||
|
||||
When contributing changes, state that you agree to license your contribution
|
||||
under the same terms as the existing code by putting this at the bottom of your
|
||||
commit message:
|
||||
|
||||
```
|
||||
|
||||
I agree to license my contributions to each file under the terms given
|
||||
at the top of each file I changed.
|
||||
```
|
||||
|
||||
Currently, the biggest needs for this library are:
|
||||
|
||||
* Unit tests.
|
||||
* Documentation.
|
||||
* More examples.
|
||||
* Static analysis and fuzzing.
|
||||
|
||||
|
||||
|
||||
Online Automated Testing
|
||||
------------------------
|
||||
|
||||
Travis CI is used for Android, Linux, and Mac OS X. The tests are run for the
|
||||
current release of each Rust channel (Stable, Beta, Nightly). Since
|
||||
untrusted.rs only depends on libcore and it only uses 100% cross-platform code
|
||||
without using `unsafe`, it should work anywhere as long as these platforms are
|
||||
passing.
|
||||
|
||||
<a title="Build Status" href=https://travis-ci.org/briansmith/untrusted><img src=https://travis-ci.org/briansmith/untrusted.svg?branch=master></a>
|
||||
|
||||
|
||||
|
||||
Bug Reporting
|
||||
-------------
|
||||
|
||||
Please report bugs either as pull requests or as issues in [the issue
|
||||
tracker](https://github.com/briansmith/untrusted/issues). untrusted.rs has a
|
||||
**full disclosure** vulnerability policy. **Please do NOT attempt to report
|
||||
any security vulnerability in this code privately to anybody.**
|
||||
|
||||
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
See [LICENSE.txt](LICENSE.txt), an ISC-style (simplified MIT) license.
|
||||
13
zeroidc/vendor/untrusted/rustfmt.toml
vendored
Normal file
13
zeroidc/vendor/untrusted/rustfmt.toml
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
edition = "2018"
|
||||
fn_args_density = "Compressed"
|
||||
fn_single_line = true
|
||||
match_arm_blocks = false
|
||||
match_block_trailing_comma = true
|
||||
max_width = 100
|
||||
merge_imports = true
|
||||
newline_style = "Unix"
|
||||
reorder_imports = true
|
||||
trailing_comma = "Vertical"
|
||||
use_field_init_shorthand = true
|
||||
use_try_shorthand = true
|
||||
wrap_comments = true
|
||||
374
zeroidc/vendor/untrusted/src/untrusted.rs
vendored
Normal file
374
zeroidc/vendor/untrusted/src/untrusted.rs
vendored
Normal file
@@ -0,0 +1,374 @@
|
||||
// Copyright 2015-2016 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
//! untrusted.rs: Safe, fast, zero-panic, zero-crashing, zero-allocation
|
||||
//! parsing of untrusted inputs in Rust.
|
||||
//!
|
||||
//! <code>git clone https://github.com/briansmith/untrusted</code>
|
||||
//!
|
||||
//! untrusted.rs goes beyond Rust's normal safety guarantees by also
|
||||
//! guaranteeing that parsing will be panic-free, as long as
|
||||
//! `untrusted::Input::as_slice_less_safe()` is not used. It avoids copying
|
||||
//! data and heap allocation and strives to prevent common pitfalls such as
|
||||
//! accidentally parsing input bytes multiple times. In order to meet these
|
||||
//! goals, untrusted.rs is limited in functionality such that it works best for
|
||||
//! input languages with a small fixed amount of lookahead such as ASN.1, TLS,
|
||||
//! TCP/IP, and many other networking, IPC, and related protocols. Languages
|
||||
//! that require more lookahead and/or backtracking require some significant
|
||||
//! contortions to parse using this framework. It would not be realistic to use
|
||||
//! it for parsing programming language code, for example.
|
||||
//!
|
||||
//! The overall pattern for using untrusted.rs is:
|
||||
//!
|
||||
//! 1. Write a recursive-descent-style parser for the input language, where the
|
||||
//! input data is given as a `&mut untrusted::Reader` parameter to each
|
||||
//! function. Each function should have a return type of `Result<V, E>` for
|
||||
//! some value type `V` and some error type `E`, either or both of which may
|
||||
//! be `()`. Functions for parsing the lowest-level language constructs
|
||||
//! should be defined. Those lowest-level functions will parse their inputs
|
||||
//! using `::read_byte()`, `Reader::peek()`, and similar functions.
|
||||
//! Higher-level language constructs are then parsed by calling the
|
||||
//! lower-level functions in sequence.
|
||||
//!
|
||||
//! 2. Wrap the top-most functions of your recursive-descent parser in
|
||||
//! functions that take their input data as an `untrusted::Input`. The
|
||||
//! wrapper functions should call the `Input`'s `read_all` (or a variant
|
||||
//! thereof) method. The wrapper functions are the only ones that should be
|
||||
//! exposed outside the parser's module.
|
||||
//!
|
||||
//! 3. After receiving the input data to parse, wrap it in an `untrusted::Input`
|
||||
//! using `untrusted::Input::from()` as early as possible. Pass the
|
||||
//! `untrusted::Input` to the wrapper functions when they need to be parsed.
|
||||
//!
|
||||
//! In general parsers built using `untrusted::Reader` do not need to explicitly
|
||||
//! check for end-of-input unless they are parsing optional constructs, because
|
||||
//! `Reader::read_byte()` will return `Err(EndOfInput)` on end-of-input.
|
||||
//! Similarly, parsers using `untrusted::Reader` generally don't need to check
|
||||
//! for extra junk at the end of the input as long as the parser's API uses the
|
||||
//! pattern described above, as `read_all` and its variants automatically check
|
||||
//! for trailing junk. `Reader::skip_to_end()` must be used when any remaining
|
||||
//! unread input should be ignored without triggering an error.
|
||||
//!
|
||||
//! untrusted.rs works best when all processing of the input data is done
|
||||
//! through the `untrusted::Input` and `untrusted::Reader` types. In
|
||||
//! particular, avoid trying to parse input data using functions that take
|
||||
//! byte slices. However, when you need to access a part of the input data as
|
||||
//! a slice to use a function that isn't written using untrusted.rs,
|
||||
//! `Input::as_slice_less_safe()` can be used.
|
||||
//!
|
||||
//! It is recommend to use `use untrusted;` and then `untrusted::Input`,
|
||||
//! `untrusted::Reader`, etc., instead of using `use untrusted::*`. Qualifying
|
||||
//! the names with `untrusted` helps remind the reader of the code that it is
|
||||
//! dealing with *untrusted* input.
|
||||
//!
|
||||
//! # Examples
|
||||
//!
|
||||
//! [*ring*](https://github.com/briansmith/ring)'s parser for the subset of
|
||||
//! ASN.1 DER it needs to understand,
|
||||
//! [`ring::der`](https://github.com/briansmith/ring/blob/master/src/der.rs),
|
||||
//! is built on top of untrusted.rs. *ring* also uses untrusted.rs to parse ECC
|
||||
//! public keys, RSA PKCS#1 1.5 padding, and for all other parsing it does.
|
||||
//!
|
||||
//! All of [webpki](https://github.com/briansmith/webpki)'s parsing of X.509
|
||||
//! certificates (also ASN.1 DER) is done using untrusted.rs.
|
||||
|
||||
#![doc(html_root_url = "https://briansmith.org/rustdoc/")]
|
||||
// `#[derive(...)]` uses `#[allow(unused_qualifications)]` internally.
|
||||
#![deny(unused_qualifications)]
|
||||
#![forbid(
|
||||
anonymous_parameters,
|
||||
box_pointers,
|
||||
missing_docs,
|
||||
trivial_casts,
|
||||
trivial_numeric_casts,
|
||||
unsafe_code,
|
||||
unstable_features,
|
||||
unused_extern_crates,
|
||||
unused_import_braces,
|
||||
unused_results,
|
||||
variant_size_differences,
|
||||
warnings
|
||||
)]
|
||||
#![no_std]
|
||||
|
||||
/// A wrapper around `&'a [u8]` that helps in writing panic-free code.
|
||||
///
|
||||
/// No methods of `Input` will ever panic.
|
||||
#[derive(Clone, Copy, Debug, Eq)]
|
||||
pub struct Input<'a> {
|
||||
value: no_panic::Slice<'a>,
|
||||
}
|
||||
|
||||
impl<'a> Input<'a> {
|
||||
/// Construct a new `Input` for the given input `bytes`.
|
||||
pub const fn from(bytes: &'a [u8]) -> Self {
|
||||
// This limit is important for avoiding integer overflow. In particular,
|
||||
// `Reader` assumes that an `i + 1 > i` if `input.value.get(i)` does
|
||||
// not return `None`. According to the Rust language reference, the
|
||||
// maximum object size is `core::isize::MAX`, and in practice it is
|
||||
// impossible to create an object of size `core::usize::MAX` or larger.
|
||||
Self {
|
||||
value: no_panic::Slice::new(bytes),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if the input is empty and false otherwise.
|
||||
#[inline]
|
||||
pub fn is_empty(&self) -> bool { self.value.is_empty() }
|
||||
|
||||
/// Returns the length of the `Input`.
|
||||
#[inline]
|
||||
pub fn len(&self) -> usize { self.value.len() }
|
||||
|
||||
/// Calls `read` with the given input as a `Reader`, ensuring that `read`
|
||||
/// consumed the entire input. If `read` does not consume the entire input,
|
||||
/// `incomplete_read` is returned.
|
||||
pub fn read_all<F, R, E>(&self, incomplete_read: E, read: F) -> Result<R, E>
|
||||
where
|
||||
F: FnOnce(&mut Reader<'a>) -> Result<R, E>,
|
||||
{
|
||||
let mut input = Reader::new(*self);
|
||||
let result = read(&mut input)?;
|
||||
if input.at_end() {
|
||||
Ok(result)
|
||||
} else {
|
||||
Err(incomplete_read)
|
||||
}
|
||||
}
|
||||
|
||||
/// Access the input as a slice so it can be processed by functions that
|
||||
/// are not written using the Input/Reader framework.
|
||||
#[inline]
|
||||
pub fn as_slice_less_safe(&self) -> &'a [u8] { self.value.as_slice_less_safe() }
|
||||
}
|
||||
|
||||
impl<'a> From<&'a [u8]> for Input<'a> {
|
||||
#[inline]
|
||||
fn from(value: &'a [u8]) -> Self { Self { value: no_panic::Slice::new(value)} }
|
||||
}
|
||||
|
||||
// #[derive(PartialEq)] would result in lifetime bounds that are
|
||||
// unnecessarily restrictive; see
|
||||
// https://github.com/rust-lang/rust/issues/26925.
|
||||
impl PartialEq<Input<'_>> for Input<'_> {
|
||||
#[inline]
|
||||
fn eq(&self, other: &Input) -> bool {
|
||||
self.as_slice_less_safe() == other.as_slice_less_safe()
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<[u8]> for Input<'_> {
|
||||
#[inline]
|
||||
fn eq(&self, other: &[u8]) -> bool { self.as_slice_less_safe() == other }
|
||||
}
|
||||
|
||||
impl PartialEq<Input<'_>> for [u8] {
|
||||
#[inline]
|
||||
fn eq(&self, other: &Input) -> bool { other.as_slice_less_safe() == self }
|
||||
}
|
||||
|
||||
/// Calls `read` with the given input as a `Reader`, ensuring that `read`
|
||||
/// consumed the entire input. When `input` is `None`, `read` will be
|
||||
/// called with `None`.
|
||||
pub fn read_all_optional<'a, F, R, E>(
|
||||
input: Option<Input<'a>>, incomplete_read: E, read: F,
|
||||
) -> Result<R, E>
|
||||
where
|
||||
F: FnOnce(Option<&mut Reader<'a>>) -> Result<R, E>,
|
||||
{
|
||||
match input {
|
||||
Some(input) => {
|
||||
let mut input = Reader::new(input);
|
||||
let result = read(Some(&mut input))?;
|
||||
if input.at_end() {
|
||||
Ok(result)
|
||||
} else {
|
||||
Err(incomplete_read)
|
||||
}
|
||||
},
|
||||
None => read(None),
|
||||
}
|
||||
}
|
||||
|
||||
/// A read-only, forward-only* cursor into the data in an `Input`.
|
||||
///
|
||||
/// Using `Reader` to parse input helps to ensure that no byte of the input
|
||||
/// will be accidentally processed more than once. Using `Reader` in
|
||||
/// conjunction with `read_all` and `read_all_optional` helps ensure that no
|
||||
/// byte of the input is accidentally left unprocessed. The methods of `Reader`
|
||||
/// never panic, so `Reader` also assists the writing of panic-free code.
|
||||
///
|
||||
/// \* `Reader` is not strictly forward-only because of the method
|
||||
/// `get_input_between_marks`, which is provided mainly to support calculating
|
||||
/// digests over parsed data.
|
||||
#[derive(Debug)]
|
||||
pub struct Reader<'a> {
|
||||
input: no_panic::Slice<'a>,
|
||||
i: usize,
|
||||
}
|
||||
|
||||
/// An index into the already-parsed input of a `Reader`.
|
||||
pub struct Mark {
|
||||
i: usize,
|
||||
}
|
||||
|
||||
impl<'a> Reader<'a> {
|
||||
/// Construct a new Reader for the given input. Use `read_all` or
|
||||
/// `read_all_optional` instead of `Reader::new` whenever possible.
|
||||
#[inline]
|
||||
pub fn new(input: Input<'a>) -> Self {
|
||||
Self {
|
||||
input: input.value,
|
||||
i: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if the reader is at the end of the input, and `false`
|
||||
/// otherwise.
|
||||
#[inline]
|
||||
pub fn at_end(&self) -> bool { self.i == self.input.len() }
|
||||
|
||||
/// Returns an `Input` for already-parsed input that has had its boundaries
|
||||
/// marked using `mark`.
|
||||
#[inline]
|
||||
pub fn get_input_between_marks(
|
||||
&self, mark1: Mark, mark2: Mark,
|
||||
) -> Result<Input<'a>, EndOfInput> {
|
||||
self.input
|
||||
.subslice(mark1.i..mark2.i)
|
||||
.map(|subslice| Input { value: subslice })
|
||||
.ok_or(EndOfInput)
|
||||
}
|
||||
|
||||
/// Return the current position of the `Reader` for future use in a call
|
||||
/// to `get_input_between_marks`.
|
||||
#[inline]
|
||||
pub fn mark(&self) -> Mark { Mark { i: self.i } }
|
||||
|
||||
/// Returns `true` if there is at least one more byte in the input and that
|
||||
/// byte is equal to `b`, and false otherwise.
|
||||
#[inline]
|
||||
pub fn peek(&self, b: u8) -> bool {
|
||||
match self.input.get(self.i) {
|
||||
Some(actual_b) => b == *actual_b,
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Reads the next input byte.
|
||||
///
|
||||
/// Returns `Ok(b)` where `b` is the next input byte, or `Err(EndOfInput)`
|
||||
/// if the `Reader` is at the end of the input.
|
||||
#[inline]
|
||||
pub fn read_byte(&mut self) -> Result<u8, EndOfInput> {
|
||||
match self.input.get(self.i) {
|
||||
Some(b) => {
|
||||
self.i += 1; // safe from overflow; see Input::from().
|
||||
Ok(*b)
|
||||
},
|
||||
None => Err(EndOfInput),
|
||||
}
|
||||
}
|
||||
|
||||
/// Skips `num_bytes` of the input, returning the skipped input as an
|
||||
/// `Input`.
|
||||
///
|
||||
/// Returns `Ok(i)` if there are at least `num_bytes` of input remaining,
|
||||
/// and `Err(EndOfInput)` otherwise.
|
||||
#[inline]
|
||||
pub fn read_bytes(&mut self, num_bytes: usize) -> Result<Input<'a>, EndOfInput> {
|
||||
let new_i = self.i.checked_add(num_bytes).ok_or(EndOfInput)?;
|
||||
let ret = self
|
||||
.input
|
||||
.subslice(self.i..new_i)
|
||||
.map(|subslice| Input { value: subslice })
|
||||
.ok_or(EndOfInput)?;
|
||||
self.i = new_i;
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
/// Skips the reader to the end of the input, returning the skipped input
|
||||
/// as an `Input`.
|
||||
#[inline]
|
||||
pub fn read_bytes_to_end(&mut self) -> Input<'a> {
|
||||
let to_skip = self.input.len() - self.i;
|
||||
self.read_bytes(to_skip).unwrap()
|
||||
}
|
||||
|
||||
/// Calls `read()` with the given input as a `Reader`. On success, returns a
|
||||
/// pair `(bytes_read, r)` where `bytes_read` is what `read()` consumed and
|
||||
/// `r` is `read()`'s return value.
|
||||
pub fn read_partial<F, R, E>(&mut self, read: F) -> Result<(Input<'a>, R), E>
|
||||
where
|
||||
F: FnOnce(&mut Reader<'a>) -> Result<R, E>,
|
||||
{
|
||||
let start = self.i;
|
||||
let r = read(self)?;
|
||||
let bytes_read = Input {
|
||||
value: self.input.subslice(start..self.i).unwrap()
|
||||
};
|
||||
Ok((bytes_read, r))
|
||||
}
|
||||
|
||||
/// Skips `num_bytes` of the input.
|
||||
///
|
||||
/// Returns `Ok(i)` if there are at least `num_bytes` of input remaining,
|
||||
/// and `Err(EndOfInput)` otherwise.
|
||||
#[inline]
|
||||
pub fn skip(&mut self, num_bytes: usize) -> Result<(), EndOfInput> {
|
||||
self.read_bytes(num_bytes).map(|_| ())
|
||||
}
|
||||
|
||||
/// Skips the reader to the end of the input.
|
||||
#[inline]
|
||||
pub fn skip_to_end(&mut self) -> () { let _ = self.read_bytes_to_end(); }
|
||||
}
|
||||
|
||||
/// The error type used to indicate the end of the input was reached before the
|
||||
/// operation could be completed.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub struct EndOfInput;
|
||||
|
||||
mod no_panic {
|
||||
use core;
|
||||
|
||||
/// A wrapper around a slice that exposes no functions that can panic.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub struct Slice<'a> {
|
||||
bytes: &'a [u8],
|
||||
}
|
||||
|
||||
impl<'a> Slice<'a> {
|
||||
#[inline]
|
||||
pub const fn new(bytes: &'a [u8]) -> Self { Self { bytes } }
|
||||
|
||||
#[inline]
|
||||
pub fn get(&self, i: usize) -> Option<&u8> { self.bytes.get(i) }
|
||||
|
||||
#[inline]
|
||||
pub fn subslice(&self, r: core::ops::Range<usize>) -> Option<Self> {
|
||||
self.bytes.get(r).map(|bytes| Self { bytes })
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_empty(&self) -> bool { self.bytes.is_empty() }
|
||||
|
||||
#[inline]
|
||||
pub fn len(&self) -> usize { self.bytes.len() }
|
||||
|
||||
#[inline]
|
||||
pub fn as_slice_less_safe(&self) -> &'a [u8] { self.bytes }
|
||||
}
|
||||
|
||||
} // mod no_panic
|
||||
98
zeroidc/vendor/untrusted/tests/tests.rs
vendored
Normal file
98
zeroidc/vendor/untrusted/tests/tests.rs
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
// Copyright 2015-2019 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
#[test]
|
||||
fn test_input_from() { let _ = untrusted::Input::from(b"foo"); }
|
||||
|
||||
#[test]
|
||||
fn test_input_is_empty() {
|
||||
let input = untrusted::Input::from(b"");
|
||||
assert!(input.is_empty());
|
||||
let input = untrusted::Input::from(b"foo");
|
||||
assert!(!input.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_len() {
|
||||
let input = untrusted::Input::from(b"foo");
|
||||
assert_eq!(input.len(), 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_read_all() {
|
||||
let input = untrusted::Input::from(b"foo");
|
||||
let result = input.read_all(untrusted::EndOfInput, |input| {
|
||||
assert_eq!(b'f', input.read_byte()?);
|
||||
assert_eq!(b'o', input.read_byte()?);
|
||||
assert_eq!(b'o', input.read_byte()?);
|
||||
assert!(input.at_end());
|
||||
Ok(())
|
||||
});
|
||||
assert_eq!(result, Ok(()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_read_all_unconsume() {
|
||||
let input = untrusted::Input::from(b"foo");
|
||||
let result = input.read_all(untrusted::EndOfInput, |input| {
|
||||
assert_eq!(b'f', input.read_byte()?);
|
||||
assert!(!input.at_end());
|
||||
Ok(())
|
||||
});
|
||||
assert_eq!(result, Err(untrusted::EndOfInput));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_as_slice_less_safe() {
|
||||
let slice = b"foo";
|
||||
let input = untrusted::Input::from(slice);
|
||||
assert_eq!(input.as_slice_less_safe(), slice);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn using_reader_after_skip_and_get_error_returns_error_must_not_panic() {
|
||||
let input = untrusted::Input::from(&[]);
|
||||
let r = input.read_all(untrusted::EndOfInput, |input| {
|
||||
let r = input.read_bytes(1);
|
||||
assert_eq!(r, Err(untrusted::EndOfInput));
|
||||
Ok(input.read_bytes_to_end())
|
||||
});
|
||||
let _ = r; // "Use" r. The value of `r` is undefined here.
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn size_assumptions() {
|
||||
// Assume that a pointer can address any point in the address space, and
|
||||
// infer that this implies that a byte slice will never be
|
||||
// `core::usize::MAX` bytes long.
|
||||
assert_eq!(core::mem::size_of::<*const u8>(), core::mem::size_of::<usize>());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn const_fn() {
|
||||
const _INPUT: untrusted::Input<'static> = untrusted::Input::from(&[]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vec_into() {
|
||||
extern crate std;
|
||||
let vec = vec![0u8; 0];
|
||||
let _x: untrusted::Input = (&vec[..]).into();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_slice() {
|
||||
let slice: &[u8] = &[0u8];
|
||||
let _x: untrusted::Input = slice.into();
|
||||
}
|
||||
Reference in New Issue
Block a user