Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Native decoder verification

The decoder is checked against the pinned Google C decoder and independent wire fixtures. Decoder mechanics describe the implementation; validation describes the library-wide contracts.

Oracle and data flow

google-brotli-ffi is a development dependency. C encoding in tests/decode_support/c_encoder.rs produces input independently of the Rust encoder. tests/decode_support/wire.rs writes explicit RFC fields. Experimental oracle builds enable BROTLI_EXPERIMENTAL; extended decoding enables C’s Large Window option. Both decoders receive the same ordered dictionary attachments.

flowchart LR
    CProducer[C one-shot, streaming and CLI] --> Bytes[compressed bytes]
    Wire[independent RFC field assembler] --> Bytes
    Bytes --> C[C decoder]
    Bytes --> Rust[Rust decoder in isolated feature profiles]
    C --> Compare[payload and consumed member boundary]
    Rust --> Compare
    Expected[original input or fixture expectation] --> Compare
    Rust --> Contracts[chunking, limits, allocation, lifecycle and I/O faults]

The fixture manifest records producer, flags, dictionary recipes, schedules, lengths and hashes for saved fixtures. Vendored compressed fixtures with unknown original flags establish format compatibility, not a specific producer parameter combination.

Coverage by boundary

BoundaryChecks
ParametersSource qualities 0–11, modes, windows, block sizes, size hints and all legal distance-parameter pairs
Wire formatRaw/compressed/metadata/final blocks, Huffman repeats, context maps, padding and built-in transforms
SchedulingPROCESS/FLUSH/FINISH, C TakeOutput, continuations, every split of small fixtures and short output buffers
DictionariesOrdered RAW attachments, prepared/decode-only views; serialized/custom transforms and contexts with experimental
CompletionTruncation, tails, concatenated members, aggregate budgets and reader read-ahead
ResourcesAllocation failures, exact input/output/workspace limits, retention, recovery and I/O retry
Large inputsIgnored release tests for real 25–30-bit distances and cumulative output beyond 4 GiB
PlatformsFallback and host SIMD execution; isolated codec imports and alloc-only compile checks

These checks run in separate std and no_std profiles, each with and without experimental. I/O tests require std APIs. --all-features activates no_std and does not replace the std profile. Feature isolation scripts also verify that unsupported imports fail to compile.

Running checks

Use development for workspace, coverage and AFL commands. The isolated decoder gates and an alloc-only target check are:

python3 scripts/check_decoder_features.py
cargo check --lib --no-default-features --features no_std,decompression --target thumbv7em-none-eabi --locked

Run ignored heavy tests separately; they regenerate large output through bounded buffers and can require nearly 3 GiB of combined history:

cargo test --release --locked --no-default-features --features std,decompression --test decompress_heavy -- --ignored --nocapture --test-threads=1

Repeat with std,decompression,experimental, no_std,decompression, and no_std,decompression,experimental. CI runs this matrix on v* tags and manual dispatch. Miri, AddressSanitizer and the decoder AFL targets provide additional checks; committed regressions replay through the same target bodies.

Known gaps and oracle limits

  • C verifies windows only through 30 bits. Windows 31–62 use independent headers and a full-width distance model, without allocating those physical windows.
  • Rust supports prefix-to-history copies that the pinned C decoder rejects when a copy exceeds the complete prefix. Independent fixtures check this extension.
  • The RAW continuation producer uses nonzero caller output buffers: a TakeOutput-only schedule can leave C’s restart bytes pending and fail its own round trip. Ordinary TakeOutput cases are tested separately.
  • A bare-metal compile check is not a 32-bit or Arm runtime test. Backend correctness needs execution on a host supporting that backend.
  • The raw decoder does not decode Shared Brotli framing containers.
  • Passing bounded tests and fuzz campaigns does not prove absence of bugs.