Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 6 additions & 15 deletions Tests/test_file_jpeg2k.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,23 +229,14 @@ def test_header_errors() -> None:
pass


def test_oversized_box_length() -> None:
# Do not raise an OverflowError() when seeking to the end of a box
@pytest.mark.parametrize("tbox", (b"", b"jp2h"))
def test_oversized_box_length(tbox: bytes) -> None:
# Do not raise an OverflowError() when seeking to the end of a box,
# or when reading the contents of a box
data = (
b"\x00\x00\x00\x0cjP \x0d\x0a\x87\x0a" # JP2 signature box
+ struct.pack(">I4s", 1, b"") # box with 64-bit length
+ struct.pack(">Q", 2**63 - 12) # length beyond the seek range
)
with pytest.raises(SyntaxError, match="Box length too large"):
Jpeg2KImagePlugin.Jpeg2KImageFile(BytesIO(data))


def test_oversized_box_length_when_reading() -> None:
# Do not raise an OverflowError() when reading the contents of a box
data = (
b"\x00\x00\x00\x0cjP \x0d\x0a\x87\x0a" # JP2 signature box
+ struct.pack(">I4s", 1, b"jp2h") # box read into with a 64-bit length
+ struct.pack(">Q", 16 + 2**63) # length whose contents overflow fp.read()
+ struct.pack(">I4s", 1, tbox) # box with 64-bit length
+ struct.pack(">Q", 2**63 - 12) # oversized length
)
with pytest.raises(SyntaxError, match="Box length too large"):
Jpeg2KImagePlugin.Jpeg2KImageFile(BytesIO(data))
Expand Down
12 changes: 6 additions & 6 deletions src/PIL/Jpeg2KImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ def _read_bytes(self, num_bytes: int) -> bytes:
if not self._can_read(num_bytes):
msg = "Not enough data in header"
raise SyntaxError(msg)
if self.fp.tell() + num_bytes >= 2**63:
msg = "Box length too large"
raise SyntaxError(msg)

data = self.fp.read(num_bytes)
if len(data) < num_bytes:
Expand Down Expand Up @@ -83,6 +86,9 @@ def has_next_box(self) -> bool:
def next_box_type(self) -> bytes:
# Skip the rest of the box if it has not been read
if self.remaining_in_box > 0:
if self.fp.tell() + self.remaining_in_box >= 2**63:
msg = "Box length too large"
raise SyntaxError(msg)
self.fp.seek(self.remaining_in_box, os.SEEK_CUR)
self.remaining_in_box = -1

Expand All @@ -98,12 +104,6 @@ def next_box_type(self) -> bytes:
msg = "Invalid header length"
raise SyntaxError(msg)

# Reject a box whose contents would extend beyond the maximum position
# that can be sought or read, before it is stored and later consumed
if self.fp.tell() + lbox - hlen >= 2**63:
msg = "Box length too large"
raise SyntaxError(msg)

self.remaining_in_box = lbox - hlen
return tbox

Expand Down
Loading