Skip to content

Handle unexpected EOF in JPEG header - #10150

Merged
radarhere merged 3 commits into
python-pillow:mainfrom
Kesavamoorthig06:fix/jpeg-marker-eof
Oct 10, 2026
Merged

radarhere merged 3 commits into
python-pillow:mainfrom
Kesavamoorthig06:fix/jpeg-marker-eof

Conversation

@Kesavamoorthig06

Copy link
Copy Markdown
Contributor

Seeking to an MPO frame whose offset points at data that isn't a JPEG stream crashes with an unhandled IndexError:

  File ".../PIL/MpoImagePlugin.py", line 164, in seek
    JpegImagePlugin.JpegImageFile._open(self)
  File ".../PIL/JpegImagePlugin.py", line 379, in _open
    i = s[0]
IndexError: index out of range

The marker scan in JpegImageFile._open skips non-0xFF junk one byte at a time:

else:
    # Skip non-0xFF junk
    s = self.fp.read(1)
    continue

If the file ends while skipping junk, read(1) returns b"" and the next loop iteration does s[0] on empty bytes. When _open runs during Image.open, ImageFile wraps that error, but MpoImageFile.seek calls _open directly, so the raw IndexError escapes to the caller.

This PR raises SyntaxError("unexpected end of file") when the scan runs out of data, both in the junk-skip path and when EOF cuts a 0xFF marker in half (which otherwise fails i16 with a struct.error).

Reproducer: Tests/images/mpo_junk_frame.mpo (added in this PR) is a normal two-frame MPO whose second-frame offset was hexedited to point at data that isn't a JPEG stream. On unpatched Pillow, im.seek(1) raises IndexError; with this PR it raises SyntaxError.

Tests added: test_mp_junk_frame_offset in Tests/test_file_mpo.py and test_eof_while_skipping_junk in Tests/test_file_jpeg.py.

@radarhere radarhere added the 🤖-assisted AI-assisted label Oct 7, 2026
@radarhere
radarhere force-pushed the fix/jpeg-marker-eof branch from 6a5a740 to c11b9dc Compare October 9, 2026 13:00
@radarhere
radarhere force-pushed the fix/jpeg-marker-eof branch from c11b9dc to 808a983 Compare October 10, 2026 04:25
@radarhere radarhere changed the title Raise SyntaxError for unexpected EOF in JPEG marker scan Handle unexpected EOF in JPEG header Oct 10, 2026
@radarhere radarhere added the JPEG label Oct 10, 2026
@radarhere

Copy link
Copy Markdown
Member

I've opted to exit the loop, instead of raising a specific error. I think this is more inline with how Pillow behaves, and still solves your problem.

@radarhere
radarhere enabled auto-merge (squash) October 10, 2026 04:28
@radarhere
radarhere merged commit 1713a67 into python-pillow:main Oct 10, 2026
51 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants