Skip to content

Raise SyntaxError instead of OverflowError for oversized JPEG 2000 box#9818

Open
nevercodecorrect wants to merge 7 commits into
python-pillow:mainfrom
nevercodecorrect:jp2-oversized-box-length
Open

Raise SyntaxError instead of OverflowError for oversized JPEG 2000 box#9818
nevercodecorrect wants to merge 7 commits into
python-pillow:mainfrom
nevercodecorrect:jp2-oversized-box-length

Conversation

@nevercodecorrect

Copy link
Copy Markdown

Fixes #9817 .

JPEG 2000's BoxReader accepts an extended 64-bit box length with no bound (the top-level reader has no known length), then passes it to fp.seek(..., SEEK_CUR), raising OverflowError from Image.open() on malformed input.
This is the JP2 counterpart of #9811 (TIFF, fixed in #9816). The box is now rejected as a malformed header (SyntaxError → UnidentifiedImageError), consistent with the plugin's other #checks.

Changes proposed in this pull request:

  • In function def next_box_type(self), add a check to reject a box whose contents end beyond the maximum seekable position
  • Add a test case.

@radarhere radarhere added the JPEG label Jul 23, 2026
Comment thread Tests/test_file_jpeg2k.py Outdated
nevercodecorrect and others added 2 commits July 23, 2026 14:35
Update payload to match the one in def _accept(prefix: bytes) -> bool:

Co-authored-by: Andrew Murray <3112309+radarhere@users.noreply.github.com>
@radarhere

Copy link
Copy Markdown
Member

I've created nevercodecorrect#1 with a suggestion.

Raise error when seeking, rather than when starting box
@nevercodecorrect

Copy link
Copy Markdown
Author

Thank you. This actually makes more sense. I have applied it.

radarhere
radarhere previously approved these changes Jul 23, 2026
Consider new position, not just offset
@nevercodecorrect

Copy link
Copy Markdown
Author

Change the location again as I think there could be two locations causing problem. One is seek() another is read()

The previous guard only rejected an oversized box length on the seek
path in next_box_type(). A box that is descended into via read_boxes()
(e.g. the jp2h header box) still passed the huge length to
BytesIO.read(), leaking OverflowError out of Image.open().

Move the check to the point where the length is stored, so it protects
both consumers of remaining_in_box: the seek in next_box_type() and the
read in read_boxes(). Add regression tests that independently trigger
the seek path and the read path.
@nevercodecorrect
nevercodecorrect force-pushed the jp2-oversized-box-length branch from a1ead53 to 196974e Compare July 23, 2026 14:17
@radarhere
radarhere dismissed their stale review July 24, 2026 02:35

Code updated

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.

Oversized JPEG 2000 box length leaks OverflowError from Image.open()

2 participants