Skip to content
Draft
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
12 changes: 12 additions & 0 deletions Tests/test_imageops.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,18 @@ def test_contain_round() -> None:
assert new_im.height == 5


@pytest.mark.parametrize(
"operation", (ImageOps.contain, ImageOps.cover, ImageOps.pad, ImageOps.fit)
)
@pytest.mark.parametrize("size", ((0, 10), (10, 0), (-1, 10), (10, -1)))
def test_size_must_be_positive(operation, size: tuple[int, int]) -> None:
# A zero or negative dimension must raise a clear ValueError, not a
# ZeroDivisionError (or silently return a wrong-sized image).
with Image.new("RGB", (100, 50)) as im:
with pytest.raises(ValueError, match="height and width must be > 0"):
operation(im, size)


@pytest.mark.parametrize(
"image_name, expected_size",
(
Expand Down
9 changes: 9 additions & 0 deletions docs/releasenotes/13.0.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,12 @@ to help projects prepare for 3.15, and to ensure Pillow could be used
immediately at the release of 3.15.0 final (2026-10-01, :pep:`790`).

Pillow 13.0.0 now officially supports Python 3.15.

ImageOps invalid sizes
^^^^^^^^^^^^^^^^^^^^^^^

:py:meth:`~PIL.ImageOps.contain`, :py:meth:`~PIL.ImageOps.cover`,
:py:meth:`~PIL.ImageOps.pad` and :py:meth:`~PIL.ImageOps.fit` now raise a
``ValueError`` when the requested size has a dimension that is zero or negative.
Previously a zero height raised ``ZeroDivisionError``, and some invalid sizes
returned an incorrectly sized image.
12 changes: 12 additions & 0 deletions src/PIL/ImageOps.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,12 @@ def colorize(
return _lut(image, red + green + blue)


def _check_size(size: tuple[int, int]) -> None:
if size[0] <= 0 or size[1] <= 0:
msg = "height and width must be > 0"
raise ValueError(msg)


def contain(
image: Image.Image, size: tuple[int, int], method: int = Image.Resampling.BICUBIC
) -> Image.Image:
Expand All @@ -293,6 +299,8 @@ def contain(
:return: An image.
"""

_check_size(size)

im_ratio = image.width / image.height
dest_ratio = size[0] / size[1]

Expand Down Expand Up @@ -324,6 +332,8 @@ def cover(
:return: An image.
"""

_check_size(size)

im_ratio = image.width / image.height
dest_ratio = size[0] / size[1]

Expand Down Expand Up @@ -562,6 +572,8 @@ def fit(
:return: An image.
"""

_check_size(size)

# by Kevin Cazabon, Feb 17/2000
# kevin@cazabon.com
# https://www.cazabon.com
Expand Down
Loading