Skip to content

fix(decode): correct image size sniffing for WebP, JPEG and oriented PNG - #1

Merged
bradsec merged 1 commit into
mainfrom
fix/decode-sniff
Oct 29, 2026
Merged

bradsec merged 1 commit into
mainfrom
fix/decode-sniff

Conversation

@bradsec

@bradsec bradsec commented Oct 29, 2026

Copy link
Copy Markdown
Owner

Summary

  • Lossless WebP (VP8L): dimensions were read 3 bytes late. A 300x200 file sniffed as 1793x15681 and decoded stretched to 468x4096.
  • JPEG: the marker scan stopped at 256 KB, so a valid JPEG with large metadata before SOF was rejected with "Use a PNG, JPEG, WebP, GIF, or BMP image." The scan window now slides forward.
  • Oriented PNG: Chromium applies PNG eXIf orientation, WebKit does not. Forcing both resize sides stretched rotated PNGs in Chromium. Images that fit now decode without resize options; oversized ones pass only resizeWidth, and capBitmap trims any overshoot.

Verification

  • npm test: 321/321 pass (regression tests added for each bug, confirmed failing before the fix).
  • lint, typecheck, format check and cache-buster check are clean.
  • Browser repro (Chromium and WebKit): lossless WebP, metadata-heavy JPEG and orientation-6 PNG all decode at their native size.
  • npx playwright test: 258 passed, 1 failed (load-and-input "sample image loads and traces" on iPad). It passed 3/3 when rerun alone, so it looks flaky under the full parallel run.

- Read lossless WebP (VP8L) dimensions after the 0x2f signature byte;
  they were read 3 bytes late, so lossless WebPs decoded distorted.
- Slide the JPEG marker scan past the first 256 KB so metadata-heavy
  files (ICC profiles, extended XMP) are no longer rejected.
- Never force both resize sides in decodeImage: Chromium applies PNG
  EXIF orientation and WebKit does not, so forcing both stretched
  rotated PNGs. Fitting images decode as-is; larger ones pass a width.
@bradsec
bradsec merged commit 10dba50 into main Oct 29, 2026
5 of 7 checks passed
@bradsec
bradsec deleted the fix/decode-sniff branch October 29, 2026 22:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant