open-standards/wai/int-payload-conformance/refusals/wiv1_too_many_frames.bin
Transaction Science 10c1597b7f wai: integer decodes do only the work their streams back
A 120-byte WIV1 (16 frames of 4729 x 4729 and an 8-byte stream) ran for
about a minute and reached gigabytes before it was refused at its last
symbol, and the JSON reader panicked on a side of 2^31.

- Every integer decode (int_video, int_hyper_synth's checked conditional
  decode, int_audio, int_splat) stops at the first symbol during whose
  decode its stream runs out (stream_exhausted), before the value is used.
  The exhaustion flag is sticky, so a stream that never runs out decodes
  as before.
- A frame, a clip or a latent is allocated only as its symbols are
  decoded; int_video holds frames as RGB8 and predicts from the last
  decoded frame, and reserves nothing from n_frames.
- WIV1 caps the frame count at 2^20 and the motion-vector field at 2^26
  elements, after the frame and clip caps (too_large); refusal fixtures
  wiv1_too_many_frames and wiv1_mv_field, checked by the generator and
  the Python verifier.
- int_video::VideoJson reads each size as a usize it fits (absent
  otherwise), and caps every size before it pads a motion-vector list.
- wai-web: decodeWiv1 keeps the decoder's frames (DecodedVideo.frame(i))
  rather than concatenating the clip.
- The Python verifier refuses at the first exhausted symbol, applies the
  new caps, and refuses a non-convertible JSON source explicitly instead
  of through assert.
- integer-payloads.md §2, §3 and §7 state the early stop, the caps and
  the memory bound.

Test: tests/int_payload_preflight.rs (counting allocator) refuses five
starved payloads, the reviewer's two WIV1 among them, at the first
exhausted symbol with no allocation sized from the header, and the two
JSON headers without a panic or a header-sized allocation.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-01 19:08:03 -04:00

2.1 KiB