mirror of
https://github.com/storytold/photocraft.git
synced 2026-11-02 14:27:35 -06:00
ASCII PGM/PPM reserved a u32 (four bytes) per declared sample before reading any, against a Limits budget of one or two bytes per sample, so a 19-byte header could ask for 12 GiB. With Limits::none() a 2³¹ × 2³¹ header panics with "capacity overflow"; PBM reserved 2⁶² bytes before finding the raster missing and aborted. ASCII reservations are now capped by what the remaining bytes can hold (a PBM digit is at least a byte, a PGM/PPM sample at least a digit and a separator), and binary PBM checks the raster length before reserving. Limits::none() documents that it is still bounded by usize overflow checks, but the decoder multiplied w × h × channels, n × 2 (16-bit samples) and the PFM raster length unchecked. A new sample_count checks the product, and the length checks use checked_mul. Tests: a header alone reserves nothing (P1-P4), u32::MAX sizes are errors (P3, P5, P6, PF, P7), and ASCII files with no slack (PBM digits without separators, no trailing whitespace) still decode. The first two failed before the fix: an abort on the 2⁶² reservation, "capacity overflow" for the P2/P3 headers, and "attempt to multiply with overflow". Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>