3 releases

0.1.2 Jun 20, 2024
0.1.1 Mar 22, 2024
0.1.0 Mar 22, 2024

#153 in No standard library

Download history 7/week @ 2024-06-03 51/week @ 2024-06-10 157/week @ 2024-06-17 8/week @ 2024-06-24 7/week @ 2024-07-01 15/week @ 2024-07-08 7/week @ 2024-07-15 1/week @ 2024-07-29

229 downloads per month
Used in cbor-macro

MIT/Apache

15KB
89 lines

cboritem License: MIT OR Apache-2.0 cboritem on crates.io cboritem on docs.rs Source Code Repository

cboritem: A serialized CBOR item

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.

Library use

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.

Invariant definition

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.

Examples

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");
}

Future development

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

  • Embedded strings are UTF-8
  • No duplicate keys are present
  • Adhers to the Common Deterministic Encoding
  • Contains no indefinite-length items
  • The CBOR item conforms to some particular CDDL structure

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.

No runtime deps