Skip to content

fix(jpeg): stop the scan reader at a marker, refuse an empty scan - #212

Merged
dlamarre-dev merged 1 commit into
mainfrom
fix/jpeg-reader-marker-stop
Sep 28, 2026
Merged

dlamarre-dev merged 1 commit into
mainfrom
fix/jpeg-reader-marker-stop

Conversation

@dlamarre-dev

Copy link
Copy Markdown
Owner

Fixes the nightly Fuzz failure (run 36413702903): decodeJpeg: accepted 701 bytes and returned scan range [607, 607).

Cause

BitReader.fill() consumed the 0xFF of a marker before recognising it, so the stop lasted one padded byte. The next fill read the marker code and whatever followed as entropy data. The mutated file's scan began with FF 6F, so every coefficient came from bytes outside [scanStart, scanEnd), while findScanEnd correctly reported an empty range. Well-formed files never hit this because the reader finishes before the marker.

Fix

  • On a marker the reader steps back onto the 0xFF, so every later fill stops there and pads, still bounded by MAX_PAD_BYTES.
  • decodeScan refuses an empty scan (JpegUnsupportedError), which a permissive DHT can otherwise decode from padding alone.

Tests

  • Two regressions in src/core/jpeg-coeff.test.ts: an empty forged 8x8 scan, and a scan with one real byte, a marker, then 20 decodable bytes. Both fail before the fix and pass after.
  • The failing seed passes locally: npm run fuzz -- --iters=200000 --seed=36413702903.
  • Full vitest suite passes (1693), goldens unchanged.

🤖 Generated with Claude Code

The nightly fuzzer found a mutated 8x8 JPEG that decoded with scan range
[607, 607). BitReader.fill() advanced past the 0xFF of a marker before
noticing it, so the stop lasted one byte: the next fill read the marker
code and everything after it as entropy data, decoding coefficients from
outside [scanStart, scanEnd).

The reader now steps back onto the 0xFF, so every later fill stops there
and pads (still bounded by MAX_PAD_BYTES). decodeScan also refuses an
empty scan, which a permissive DHT can otherwise decode from padding alone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dlamarre-dev
dlamarre-dev merged commit f5a9952 into main Sep 28, 2026
10 checks passed
@dlamarre-dev
dlamarre-dev deleted the fix/jpeg-reader-marker-stop branch September 28, 2026 13:44
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