Add the missing direct coverage for parse_stss

Every other sample-table parser (stco, stsc, stts, ctts) had a "count lie"
test proving the declared count is bounded by what the box actually holds,
and stco/stsc had their own arithmetic pinned. parse_stss had neither - no
test in this file ever called it with real entries, only with a too-short
buffer. Added the same two: two distinct entries read from their own
offsets (catching the o = 8 + i*4 arithmetic and the per-entry bounds
check), and a declared count of 3 backed by only 2 real entries (catching
the same "trust the box, not the count" contract the other four parsers
already had).
This commit is contained in:
Matthew Jackson
2026-08-01 16:37:10 -07:00
parent c59e1e3342
commit e008e71a17
+48
View File
@@ -1098,6 +1098,54 @@ mod tests {
} }
} }
/// `parse_stss` had no direct positive-path test anywhere in this file —
/// only its short-buffer safety was pinned. Two real, distinct entries in
/// a buffer sized to exactly fit them (`b.len() == 16`, so the second
/// entry's `o + 4 == b.len()` exactly) separates every arithmetic mutant
/// at once: an `o = 8 + i*4` → `8 - i*4` slip reads the `count` field
/// instead of the second entry; an `i*4` → `i/4` slip re-reads the FIRST
/// entry for the second (integer division collapses `i=1` back to the
/// same offset as `i=0`); and an `o + 4 > b.len()` → `o + 4 < b.len()`
/// slip breaks out on the very first entry, because there IS more room
/// after it (`12 < 16`) — leaving the set empty instead of holding both.
#[test]
fn parse_stss_reads_two_distinct_entries_from_their_own_offsets() {
let mut b = vec![0u8, 0, 0, 0]; // version+flags
b.extend_from_slice(&2u32.to_be_bytes()); // entry_count = 2
b.extend_from_slice(&100u32.to_be_bytes());
b.extend_from_slice(&200u32.to_be_bytes());
assert_eq!(b.len(), 16, "sized to fit exactly 2 entries, no slack");
let set = parse_stss(&b);
assert_eq!(
set,
[100u32, 200u32].into_iter().collect(),
"both distinct sync sample numbers must be present"
);
}
/// A declared `count` larger than the box can hold (a lie, or a truncated
/// box) must be bounded by the per-entry guard, not by trusting the
/// count — the SAME contract `parse_stco`/`parse_stsc`/`parse_stts` pin
/// with their own "count lie" tests. Bounded HERE means the loop must
/// stop, not read past the end: an `o + 4 > b.len()` → `o - 4 > b.len()`
/// mutant almost never fires (`o - 4` stays small for every realistic
/// `o`), so it lets the loop walk straight past a truncated box into an
/// out-of-bounds `be32` read.
#[test]
fn parse_stss_count_lie_is_bounded_by_the_box_not_trusted() {
let mut b = vec![0u8, 0, 0, 0];
b.extend_from_slice(&3u32.to_be_bytes()); // declares 3, lying
b.extend_from_slice(&100u32.to_be_bytes()); // only 2 real entries
b.extend_from_slice(&200u32.to_be_bytes());
assert_eq!(b.len(), 16, "room for exactly 2 real entries, not 3");
let set = parse_stss(&b);
assert_eq!(
set,
[100u32, 200u32].into_iter().collect(),
"only the entries the box actually holds, no panic on the lie"
);
}
#[test] #[test]
fn stsc_offsets_one_sample_per_chunk() { fn stsc_offsets_one_sample_per_chunk() {
// Our writer's layout: 1 sample/chunk, co64 lists every offset. // Our writer's layout: 1 sample/chunk, co64 lists every offset.