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
13 changes: 13 additions & 0 deletions Tests/test_file_pcx.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,3 +202,16 @@ def test_break_padding(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
for x in range(5):
px[x, 3] = 0
_test_buffer_overflow(tmp_path, im, monkeypatch)


@pytest.mark.parametrize(
"data_len, rawmode",
(
(5, "P;4L"),
(3, "P;2L"),
),
)
def test_truncated(data_len: int, rawmode: str) -> None:
data = b"\x00" * data_len
with pytest.raises(ValueError, match="not enough image data"):
Image.frombuffer("P", (9, 1), data, "raw", rawmode, 0, 1)
6 changes: 6 additions & 0 deletions Tests/test_image_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ def __init__(self, img: Image.Image, arr_params: dict[str, Any]) -> None:
self.img = img
self.__array_interface__ = arr_params

def __len__(self) -> int:
return len(self.img.tobytes())

def tobytes(self) -> bytes:
return self.img.tobytes()

Expand Down Expand Up @@ -100,6 +103,9 @@ class Wrapper:
def __init__(self, arr_params: dict[str, Any]) -> None:
self.__array_interface__ = arr_params

def __len__(self) -> int:
return 1

with pytest.raises(ValueError):
wrapped = Wrapper({"shape": (1, 1), "strides": (1, 1), "typestr": "|u1"})
Image.fromarray(wrapped, "L")
Expand Down
9 changes: 9 additions & 0 deletions src/PIL/Image.py
Original file line number Diff line number Diff line change
Expand Up @@ -943,6 +943,12 @@ def frombytes(
# may pass tuple instead of argument list
decoder_args = decoder_args[0]

if decoder_args and decoder_args[0] in {"P;2L", "P;4L"}:
multiple = 4 if decoder_args[0] == "P;2L" else 8
if len(data) % multiple:
msg = "not enough image data"
raise ValueError(msg)

# default format
if decoder_name == "raw" and decoder_args == ():
decoder_args = self.mode
Expand Down Expand Up @@ -3350,6 +3356,9 @@ class SupportsArrayInterface(Protocol):
def __array_interface__(self) -> dict[str, Any]:
raise NotImplementedError()

def __len__(self) -> int:
raise NotImplementedError()


DecoderInput = bytes | bytearray | memoryview | SupportsArrayInterface

Expand Down
Loading