70 lines
8.6 KiB
HTML
70 lines
8.6 KiB
HTML
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="untrusted.rs: Safe, fast, zero-panic, zero-crashing, zero-allocation parsing of untrusted inputs in Rust."><title>untrusted - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../static.files/rustdoc-ca0dd0c4.css"><meta name="rustdoc-vars" data-root-path="../" data-static-root-path="../static.files/" data-current-crate="untrusted" data-themes="" data-resource-suffix="" data-rustdoc-version="1.93.1 (01f6ddf75 2026-02-11) (Arch Linux rust 1:1.93.1-1)" data-channel="1.93.1" data-search-js="search-9e2438ea.js" data-stringdex-js="stringdex-a3946164.js" data-settings-js="settings-c38705f0.js" ><script src="../static.files/storage-e2aeef58.js"></script><script defer src="../crates.js"></script><script defer src="../static.files/main-a410ff4d.js"></script><noscript><link rel="stylesheet" href="../static.files/noscript-263c88ec.css"></noscript><link rel="alternate icon" type="image/png" href="../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../static.files/favicon-044be391.svg"></head><body class="rustdoc mod crate"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><rustdoc-topbar><h2><a href="#">Crate untrusted</a></h2></rustdoc-topbar><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../untrusted/index.html">untrusted</a><span class="version">0.9.0</span></h2></div><div class="sidebar-elems"><ul class="block"><li><a id="all-types" href="all.html">All Items</a></li></ul><section id="rustdoc-toc"><h3><a href="#">Sections</a></h3><ul class="block top-toc"><li><a href="#examples" title="Examples">Examples</a></li></ul><h3><a href="#structs">Crate Items</a></h3><ul class="block"><li><a href="#structs" title="Structs">Structs</a></li><li><a href="#functions" title="Functions">Functions</a></li></ul></section><div id="rustdoc-modnav"></div></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><div class="width-limiter"><section id="main-content" class="content"><div class="main-heading"><h1>Crate <span>untrusted</span> <button id="copy-path" title="Copy item path to clipboard">Copy item path</button></h1><rustdoc-toolbar></rustdoc-toolbar><span class="sub-heading"><a class="src" href="../src/untrusted/lib.rs.html#15-121">Source</a> </span></div><details class="toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>untrusted.rs: Safe, fast, zero-panic, zero-crashing, zero-allocation
|
||
parsing of untrusted inputs in Rust.</p>
|
||
<p><code>git clone https://github.com/briansmith/untrusted</code></p>
|
||
<p>untrusted.rs goes beyond Rust’s normal safety guarantees by also
|
||
guaranteeing that parsing will be panic-free, as long as
|
||
<code>untrusted::Input::as_slice_less_safe()</code> 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.</p>
|
||
<p>The overall pattern for using untrusted.rs is:</p>
|
||
<ol>
|
||
<li>
|
||
<p>Write a recursive-descent-style parser for the input language, where the
|
||
input data is given as a <code>&mut untrusted::Reader</code> parameter to each
|
||
function. Each function should have a return type of <code>Result<V, E></code> for
|
||
some value type <code>V</code> and some error type <code>E</code>, either or both of which may
|
||
be <code>()</code>. Functions for parsing the lowest-level language constructs
|
||
should be defined. Those lowest-level functions will parse their inputs
|
||
using <code>::read_byte()</code>, <code>Reader::peek()</code>, and similar functions.
|
||
Higher-level language constructs are then parsed by calling the
|
||
lower-level functions in sequence.</p>
|
||
</li>
|
||
<li>
|
||
<p>Wrap the top-most functions of your recursive-descent parser in
|
||
functions that take their input data as an <code>untrusted::Input</code>. The
|
||
wrapper functions should call the <code>Input</code>’s <code>read_all</code> (or a variant
|
||
thereof) method. The wrapper functions are the only ones that should be
|
||
exposed outside the parser’s module.</p>
|
||
</li>
|
||
<li>
|
||
<p>After receiving the input data to parse, wrap it in an <code>untrusted::Input</code>
|
||
using <code>untrusted::Input::from()</code> as early as possible. Pass the
|
||
<code>untrusted::Input</code> to the wrapper functions when they need to be parsed.</p>
|
||
</li>
|
||
</ol>
|
||
<p>In general parsers built using <code>untrusted::Reader</code> do not need to explicitly
|
||
check for end-of-input unless they are parsing optional constructs, because
|
||
<code>Reader::read_byte()</code> will return <code>Err(EndOfInput)</code> on end-of-input.
|
||
Similarly, parsers using <code>untrusted::Reader</code> 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 <code>read_all</code> and its variants automatically check
|
||
for trailing junk. <code>Reader::skip_to_end()</code> must be used when any remaining
|
||
unread input should be ignored without triggering an error.</p>
|
||
<p>untrusted.rs works best when all processing of the input data is done
|
||
through the <code>untrusted::Input</code> and <code>untrusted::Reader</code> 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,
|
||
<code>Input::as_slice_less_safe()</code> can be used.</p>
|
||
<p>It is recommend to use <code>use untrusted;</code> and then <code>untrusted::Input</code>,
|
||
<code>untrusted::Reader</code>, etc., instead of using <code>use untrusted::*</code>. Qualifying
|
||
the names with <code>untrusted</code> helps remind the reader of the code that it is
|
||
dealing with <em>untrusted</em> input.</p>
|
||
<h2 id="examples"><a class="doc-anchor" href="#examples">§</a>Examples</h2>
|
||
<p><a href="https://github.com/briansmith/ring"><em>ring</em></a>’s parser for the subset of
|
||
ASN.1 DER it needs to understand,
|
||
<a href="https://github.com/briansmith/ring/blob/main/src/io/der.rs"><code>ring::der</code></a>,
|
||
is built on top of untrusted.rs. <em>ring</em> also uses untrusted.rs to parse ECC
|
||
public keys, RSA PKCS#1 1.5 padding, and for all other parsing it does.</p>
|
||
<p>All of <a href="https://github.com/briansmith/webpki">webpki</a>’s parsing of X.509
|
||
certificates (also ASN.1 DER) is done using untrusted.rs.</p>
|
||
</div></details><h2 id="structs" class="section-header">Structs<a href="#structs" class="anchor">§</a></h2><dl class="item-table"><dt><a class="struct" href="struct.EndOfInput.html" title="struct untrusted::EndOfInput">EndOf<wbr>Input</a></dt><dd>The error type used to indicate the end of the input was reached before the
|
||
operation could be completed.</dd><dt><a class="struct" href="struct.Input.html" title="struct untrusted::Input">Input</a></dt><dd>A wrapper around <code>&'a [u8]</code> that helps in writing panic-free code.</dd><dt><a class="struct" href="struct.Reader.html" title="struct untrusted::Reader">Reader</a></dt><dd>A read-only, forward-only cursor into the data in an <code>Input</code>.</dd></dl><h2 id="functions" class="section-header">Functions<a href="#functions" class="anchor">§</a></h2><dl class="item-table"><dt><a class="fn" href="fn.read_all_optional.html" title="fn untrusted::read_all_optional">read_<wbr>all_<wbr>optional</a></dt><dd>Calls <code>read</code> with the given input as a <code>Reader</code>, ensuring that <code>read</code>
|
||
consumed the entire input. When <code>input</code> is <code>None</code>, <code>read</code> will be
|
||
called with <code>None</code>.</dd></dl></section></div></main></body></html> |