diff --git a/Tests/test_file_jpeg2k.py b/Tests/test_file_jpeg2k.py index 2a69f1f9a5e..8976aea0924 100644 --- a/Tests/test_file_jpeg2k.py +++ b/Tests/test_file_jpeg2k.py @@ -2,6 +2,7 @@ import os import re +import struct from collections.abc import Generator from io import BytesIO from pathlib import Path @@ -547,6 +548,18 @@ def test_plt_marker(card: ImageFile.ImageFile) -> None: out.seek(length - 2, os.SEEK_CUR) +def test_marker_length() -> None: + magic = b"\xff\x4f\xff\x51" + b = BytesIO(magic + b"\x00\x00") + with pytest.raises(ValueError, match="SIZ marker length must be at least 38"): + Image.open(b) + + siz_marker = _binary.o16be(38) + b"\x00" * 34 + struct.pack(">H", 2) + b = BytesIO(magic + siz_marker + b"\x00" * 4) + with pytest.raises(ValueError, match="Marker length too small"): + Image.open(b) + + def test_9bit() -> None: with Image.open("Tests/images/9bit.j2k") as im: assert im.mode == "I;16" diff --git a/src/PIL/Jpeg2KImagePlugin.py b/src/PIL/Jpeg2KImagePlugin.py index cb37735300c..ca982f06aa5 100644 --- a/src/PIL/Jpeg2KImagePlugin.py +++ b/src/PIL/Jpeg2KImagePlugin.py @@ -108,6 +108,9 @@ def _parse_codestream(fp: IO[bytes]) -> tuple[tuple[int, int], str]: hdr = fp.read(2) lsiz = _binary.i16be(hdr) + if lsiz < 38: + msg = "SIZ marker length must be at least 38" + raise ValueError(msg) siz = hdr + fp.read(lsiz - 2) lsiz, rsiz, xsiz, ysiz, xosiz, yosiz, _, _, _, _, csiz = struct.unpack_from( ">HHIIIIIIIIH", siz @@ -328,6 +331,9 @@ def _parse_comment(self) -> None: break hdr = self.fp.read(2) length = _binary.i16be(hdr) + if length < 2: + msg = "Marker length too small" + raise ValueError(msg) if typ == 0x64: # Comment self.info["comment"] = self.fp.read(length - 2)[2:]