multi-util 1.0.3

Multiformat utility functions and types
// SPDX-License-Identifier: Apache-2.0
/// Errors generated by the numeric type impls
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum Error {
    /// Multitrait decode error
    #[error(transparent)]
    Multitrait(#[from] multi_trait::Error),
    /// Multicodec decode error
    #[error(transparent)]
    Multicodec(#[from] multi_codec::Error),
    /// `BaseEncoded` error
    #[error(transparent)]
    BaseEncoded(#[from] BaseEncodedError),
    /// `BaseEncoder` error
    #[error(transparent)]
    BaseEncoder(#[from] BaseEncoderError),
    /// Custom error for inner types to use when nothing else works
    #[error("Custom error: {0}")]
    Custom(String),
    /// Insufficient data available for the claimed length
    ///
    /// This error occurs when a varint length claim exceeds the available buffer size.
    /// This prevents buffer overflow attacks where an attacker claims a large length
    /// but provides minimal data.
    ///
    /// # Security
    ///
    /// This validation prevents CWE-125 (Out-of-bounds Read) vulnerabilities.
    ///
    /// # Example
    ///
    /// ```rust
    /// use multi_util::Error;
    ///
    /// // This would trigger InsufficientData:
    /// // Varint claims 1000 bytes but only 3 bytes available
    /// ```
    #[error("insufficient data: expected {expected} bytes, but only {actual} bytes available")]
    InsufficientData {
        /// The number of bytes claimed by the length prefix
        expected: usize,
        /// The actual number of bytes available in the buffer
        actual: usize,
    },
    /// Decoded length exceeds the configured maximum
    ///
    /// This error occurs when a varint length claim exceeds [`crate::varbytes::MAX_DECODED_SIZE`].
    /// Enforcing an upper bound on a single decoded `Varbytes` value prevents a peer that supplies
    /// a legitimately-sized buffer from causing the decoder to allocate an arbitrarily large
    /// `Vec<u8>` (`DoS` via memory exhaustion). The default ceiling is 16 MiB, which comfortably
    /// exceeds every legitimate multiformat payload in this stack while still bounding the
    /// worst-case allocation for untrusted wire data.
    ///
    /// # Security
    ///
    /// This validation mitigates CWE-400 (Uncontrolled Resource Consumption).
    #[error("decoded length {claimed} exceeds maximum {max}")]
    InputTooLarge {
        /// The number of bytes claimed by the length prefix
        claimed: usize,
        /// The configured maximum decoded size
        max: usize,
    },
}

impl Error {
    /// create a custom error instance
    #[must_use]
    pub fn custom(s: &str) -> Self {
        Self::Custom(s.to_string())
    }
}

/// Errors generated by the base encoding smart pointer
#[derive(Clone, Debug, thiserror::Error)]
#[non_exhaustive]
pub enum BaseEncodedError {
    /// `BaseEncoder` error
    #[error(transparent)]
    BaseEncoder(#[from] BaseEncoderError),
    /// Value decoding failed
    #[error("Failed to decode the tagged value")]
    ValueFailed,
}

/// Errors generated by the base encoding smart pointer
#[derive(Clone, Debug, thiserror::Error)]
#[non_exhaustive]
pub enum BaseEncoderError {
    /// Multibase decode error
    #[error(transparent)]
    Multibase(#[from] multi_base::Error),

    /// Base58 decode error
    #[error("Base58 error: {0}")]
    Base58(String),
}