Skip to main content

BoundedReader

Trait BoundedReader 

Source
pub trait BoundedReader {
    // Required method
    fn remaining(&self) -> usize;

    // Provided methods
    fn protocol_limits(&self) -> ProtocolLimits { ... }
    fn alloc_count_checked(
        &self,
        count: usize,
        min_bytes_per_elem: usize,
    ) -> Result<usize> { ... }
    fn with_capacity_bounded<T>(
        &self,
        count: usize,
        min_bytes_per_elem: usize,
    ) -> Vec<T> { ... }
    fn with_capacity_limited<T, F>(
        &self,
        count: usize,
        min_bytes_per_elem: usize,
        check: F,
    ) -> Result<Vec<T>>
       where F: FnOnce(&ProtocolLimits, usize) -> Result<()> { ... }
}
Expand description

The structural OOM-from-length invariant for every wire decoder.

A length/count field read from the wire can never drive an allocation larger than the bytes actually remaining in the current message buffer: you cannot have N elements if fewer than N * min_bytes_per_elem bytes remain. Every reader over an untrusted buffer (TtcReader, the OSON / DbObject / notification cursors, the VECTOR reader) implements this trait, and every count-driven Vec::with_capacity / reserve in the decoders routes through one of its two methods instead of trusting a raw u16/u32/u64 count.

This closes the OOM-from-length bug class by construction: a new decoder physically cannot pre-allocate from a wire count without going through a bound, because the raw Vec::with_capacity(count) shape is the thing we audit against (see docs/FUZZING.md).

Two flavors, both anchored on remaining:

  • alloc_count_checked — fail closed early: returns an Err if the declared count cannot possibly fit, before any allocation. Use where an oversized count is unambiguously malformed.
  • with_capacity_bounded — cap the pre-allocation at what the buffer could hold while still returning a normal growable Vec. Use where the loop body itself fails closed on the first truncated element read; legitimate large payloads keep working because the cap equals the honest count whenever the bytes are really there.

Required Methods§

Source

fn remaining(&self) -> usize

Bytes still unread in the current message buffer. The ceiling on any count-driven allocation.

Provided Methods§

Source

fn protocol_limits(&self) -> ProtocolLimits

Resource policy attached to this decoder. Readers that have not yet grown a configurable policy surface use the validated defaults.

Source

fn alloc_count_checked( &self, count: usize, min_bytes_per_elem: usize, ) -> Result<usize>

Validate a server-declared element count against the buffer: a run of count elements must carry at least count * min_bytes_per_elem bytes, so a count whose minimum byte footprint exceeds Self::remaining is a lie. Returns the (unchanged) count when it fits, or a fail-closed ProtocolError::TtcDecode otherwise — never a panic, never an OOM.

min_bytes_per_elem is the minimum on-wire size of one element (e.g. 4 for a u32 index, 8 for an f64, 1 for a length-prefixed field whose shortest legal form is a single length byte). A zero is treated as 1.

Source

fn with_capacity_bounded<T>( &self, count: usize, min_bytes_per_elem: usize, ) -> Vec<T>

Pre-size a Vec for count elements without trusting count: the reserved capacity is capped at remaining() / min_bytes_per_elem, the largest number of elements the buffer could actually hold. The returned Vec is a normal growable Vec, so a legitimately large payload (where count really fits) is pre-sized to the honest count, and a streamed / chunked field that grows past the initial buffer still appends correctly — the cap only governs the speculative up-front reservation.

Source

fn with_capacity_limited<T, F>( &self, count: usize, min_bytes_per_elem: usize, check: F, ) -> Result<Vec<T>>

Policy-aware form of with_capacity_bounded: the caller supplies the resource family check, then the speculative allocation is still capped by the remaining buffer.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§