multi-util 1.1.0

Multiformat utility functions and types
docs.rs failed to build multi-util-1.1.0
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.

multi-util

Traits, types, and functions to construct multiformat types.

Features

  • no_std support. The crate works in no_std environments with alloc.
  • Zero unsafe code. #![deny(unsafe_code)] is set at the crate root.
  • DoS protection. The Varbytes decode path enforces a decoded-size cap and a buffer-length check.
  • Configurable decoded-size cap. Use VarbytesMax<N> to set a custom cap at the type level. The default Varbytes alias uses 16 MiB.

Install

Add this to your Cargo.toml:

[dependencies]
multi-util = "1.1"

For no_std environments, disable std and serde:

[dependencies]
multi-util = { version = "1.1", default-features = false }

To use serde under no_std, enable only the serde feature:

[dependencies]
multi-util = { version = "1.1", default-features = false, features = ["serde"] }

MSRV: Rust 1.85 (Edition 2024).

Feature Flags

  • std (default). Enables std support. It pulls in the std-gated features of multi-base, multi-codec, multi-trait, thiserror, and serde.
  • serde (default). Enables serde serialization and deserialization for BaseEncoded, Varuint, and Varbytes.

BaseEncoded

The BaseEncoded smart pointer wraps any multiformat type that implements the EncodingInfo trait. BaseEncoded handles base encoding of the inner value. It uses the Multibase text encoding systems.

CodecInfo

The CodecInfo trait lets a multiformat type expose its Multicodec value to code that uses this trait.

Varuint

Varuint is an implementation of a variable length, unsigned integer. It is common to all multiformat protocols and types.

Varbytes

Varbytes is a Varuint followed by a binary octet array of equal length. It is a common way to encode arbitrary binary data. Any code can skip over the data if it does not know how, or does not want, to process it.

<varbytes> ::= <varuint> N(OCTET)
                    ^        ^
                   /          \
           count of            variable number
             octets            of octets

Decoded-Size Caps

Varbytes::try_decode_from and the serde Varbytes path enforce two caps on untrusted wire data:

  • DEFAULT_MAX = 16 MiB. This is the most bytes a single decoded Varbytes value can allocate. If the length prefix claims more, the decode returns Error::InputTooLarge.
  • Buffer-length check. If the length prefix claims more bytes than remain in the buffer, the decode returns Error::InsufficientData. This prevents an out-of-bounds read.

The serde path routes all visitor impls through a shared decode_varbytes helper. The helper runs both checks before it slices the buffer.

Configurable Cap (A4)

The decoded-size cap is configurable at the type level. VarbytesMax<const MAX: usize> is the generic struct. Varbytes is a type alias for VarbytesMax<DEFAULT_MAX> (16 MiB). To set a custom cap, instantiate VarbytesMax<N> directly:

use multi_util::varbytes::VarbytesMax;

// A Varbytes that rejects payloads over 1024 bytes.
type SmallVarbytes = VarbytesMax<1024>;

The MAX const generic sets the maximum decoded size. try_decode_from and the serde Deserialize impl both enforce it. The crate exports deserialize_varbytes_with_max(deserializer, max) for a per-field override without a distinct type.

Security

See SECURITY.md for the full security policy.

  • #![deny(unsafe_code)] is set at the crate root.
  • All errors return Result. No path panics on invalid input.
  • The Varbytes decode path enforces DEFAULT_MAX (16 MiB) and a buffer-length check. This mitigates CWE-400 and CWE-125.