Security - Remove the unsafe Vec::set_len over recycled sector buffers — UB reachable from safe code (GHSA-j8ww-f5fg-9pmh, low). Uses Vec::resize; pooling unchanged. CI / tooling - clippy on stable with the MSRV single-sourced from Cargo.toml; cargo-deny dependency-audit gate with first-party git sources allowed (#15); audience-based comment-guard (#17). Docs - README (keydb ownership, BD-J parser count), drive-access transport/reset notes, mux timeline module-doc links.
2.0 KiB
ADTS decodability gate
Module rationale (src/mux/codec/adts.rs)
Per the ADTS framing defined in ISO/IEC 13818-7 / ISO/IEC 14496-3, a header
is structurally invalid in exactly three ways this gate treats as hard
rejects: syncword != 0xFFF, a reserved sampling_frequency_index (the sample
rate table has 13 valid entries, so index >= 13 is reserved), and
aac_frame_length < 7 (shorter than the fixed+variable header itself). The
optional 16-bit ADTS CRC is not verified here — it is simply skipped. So the
gate enforces those three rejects: a packet that begins with the ADTS sync
but is otherwise malformed is dropped; a packet with no ADTS sync is raw AAC
(e.g. from an MP4 container, which carries no ADTS header) or a continuation
and passes through unchanged — never false-dropped. Raw AAC has no per-frame
integrity data, so like LPCM it cannot be gated.
Test: a_crc_present_header_shorter_than_its_own_crc_is_invalid
A header that CLAIMS a CRC (protection_absent = 0) but declares a frame length too short to contain one.
aac_frame_length counts the header and the CRC, not just the payload,
so with a CRC present the smallest structurally possible frame is 9
bytes: the 7-byte fixed+variable header plus the 16-bit crc_check.
The gate compared against a flat 7 and never read protection_absent at
all, so a frame whose own header says it is impossible was classified
Valid and forwarded to the muxer.
Test: dropped_frames_are_counted_but_their_duration_is_not_invented
A dropped ADTS frame is dropped BECAUSE its header failed validation, so the very fields a duration would come from (sampling_frequency_index, and the 1024-samples-per-AAC-frame constant applied to it) are the ones known to be untrustworthy. This gate therefore reports the drop's duration as zero rather than deriving a number from a header it has just rejected — the honest answer, and the one the count alongside it must be read with. A nonzero constant here would report silence that was never measured.