Crates.io | cboritem |
lib.rs | cboritem |
version | 0.1.2 |
source | src |
created_at | 2024-03-22 09:53:06.742784 |
updated_at | 2024-06-20 08:32:40.532718 |
description | Types for serialized CBOR items |
homepage | |
repository | https://codeberg.org/chrysn/cboritem |
max_upload_size | |
id | 1182454 |
size | 15,793 |
A CborItem<'a>
is a newtype around &'a [u8]
that upholds the invariant of
containing a single serialized CBOR item. A ThinCborItem<'a>
is its start
pointer; when accessing it, users rely on that property to stop reading at the end of the item.
In a sense, the types are similar to &str
and CStr
, respectively,
once the latter follows the plan of eventually becoming a thin pointer.
Their use is for efficiently storing pre-verified slices of CBOR items, eg. when implementing packed CBOR. They can also serve as an interface point between CBOR libraries (easing error handling because end-of-stream and bytes-after-the-data errors are panic-worthy invariants; other parsing errors may still occur if there is any well-formed data the parser can not process, or that violates basic validity requirements), and as a marker type by which CBOR parsers can be instructed to process any item into a slice for later detailed inspection.
This crate is not a CBOR library, thus it contains no functions to safely create any of its types (as that requires a CBOR parser). Instead, its intention is to be produced by CBOR parsers after they have verified that the invariant upholds.
The invariant upheld in this crate’s types is that their bytes are exactly one well-formed CBOR item as defined in RFC8949; in particular, that means they contain at least one byte.
The invariants in this crates are soundness invariants: Receivers of a CBOR item may not
just panic when they find invalid CBOR, but they may invoke undefined behavior (eg. by calling
unreachable_unchecked
. Consequently, creating a CBOR
item requires use of the unsafe
keyword, with the invariants being checked by the parser that
creates the item.
This is a necessary consequence of providing thin pointers: The invariants are relied on by users who read through a raw pointer, which on inaccurate data would result in reads beyond the original allocated object, which is undefined behavior.
use cboritem::{CborItem, ThinCborItem};
let onehundred = [0x24, 0x64];
assert_eq!(onehundred[0], 0x24);
let onehundred = unsafe { CborItem::new(&onehundred) };
let onehundred: ThinCborItem<'_> = onehundred.as_thin();
assert_eq!(core::mem::size_of_val(&onehundred), core::mem::size_of::<&u8>());
// One byte can always be read, so we don't need a CBOR parser to tell us it is safe
if onehundred.first() == 0x24 {
assert_eq!(unsafe { onehundred.offset(1).read() }, 100);
} else {
panic!("Unexpected type or integer size");
}
Later versions may add types or variants of the current types (by means of associated types with a default), eg. to descibe additional constraints such as
If any extensions are made that change CBOR’s validity rules (eg. i=28 is defined for 128-bit integer arguments), this crate would go through a major release to support them.