From 89ef6b1a173edc6fd877291e1f9111292e915049 Mon Sep 17 00:00:00 2001 From: lukegb Date: Thu, 2 Jul 2026 13:02:30 +0100 Subject: [PATCH 1/3] Avoid divide-by-zero crash in image filtering A kernel size of 1 is pointless/trivial, but it shouldn't cause the C extension to crash. --- Tests/test_image_filter.py | 8 ++++++++ src/libImaging/Filter.c | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Tests/test_image_filter.py b/Tests/test_image_filter.py index 6fe6b594f61..06f7cff3950 100644 --- a/Tests/test_image_filter.py +++ b/Tests/test_image_filter.py @@ -228,3 +228,11 @@ def test_invalid_box_blur_filter(radius: int | tuple[int, int]) -> None: box_blur_filter.radius = radius with pytest.raises(ValueError): im.filter(box_blur_filter) + +def test_rankfilter_size_1() -> None: + im = Image.new("L", (3, 3), 128) + # Size 1 should not crash (margin is 0) + assert im.filter(ImageFilter.MinFilter(1)).getpixel((1, 1)) == 128 + assert im.filter(ImageFilter.MaxFilter(1)).getpixel((1, 1)) == 128 + assert im.filter(ImageFilter.MedianFilter(1)).getpixel((1, 1)) == 128 + assert im.filter(ImageFilter.RankFilter(1, 0)).getpixel((1, 1)) == 128 diff --git a/src/libImaging/Filter.c b/src/libImaging/Filter.c index b5f971d40c2..76b5cd486f2 100644 --- a/src/libImaging/Filter.c +++ b/src/libImaging/Filter.c @@ -56,7 +56,7 @@ ImagingExpand(Imaging imIn, int margin) { if (margin < 0) { return (Imaging)ImagingError_ValueError("bad kernel size"); } - if (margin > INT_MAX / (margin * (int)sizeof(FLOAT32))) { + if (margin > 0 && margin > INT_MAX / (margin * (int)sizeof(FLOAT32))) { return (Imaging)ImagingError_ValueError("filter size too large"); } From dfe04d5ee3b25f75adb67d9c2d2ff00e7e1e6257 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 2 Jul 2026 12:12:09 +0000 Subject: [PATCH 2/3] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- Tests/test_image_filter.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Tests/test_image_filter.py b/Tests/test_image_filter.py index 06f7cff3950..8387cdeb048 100644 --- a/Tests/test_image_filter.py +++ b/Tests/test_image_filter.py @@ -229,6 +229,7 @@ def test_invalid_box_blur_filter(radius: int | tuple[int, int]) -> None: with pytest.raises(ValueError): im.filter(box_blur_filter) + def test_rankfilter_size_1() -> None: im = Image.new("L", (3, 3), 128) # Size 1 should not crash (margin is 0) From 9f7010dada2aca8457dc8b8a16df82084d3493d6 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Fri, 3 Jul 2026 09:19:31 +1000 Subject: [PATCH 3/3] Copy image if expanding by zero --- Tests/test_image_filter.py | 1 + src/_imaging.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/Tests/test_image_filter.py b/Tests/test_image_filter.py index 8387cdeb048..3f1c38be3da 100644 --- a/Tests/test_image_filter.py +++ b/Tests/test_image_filter.py @@ -232,6 +232,7 @@ def test_invalid_box_blur_filter(radius: int | tuple[int, int]) -> None: def test_rankfilter_size_1() -> None: im = Image.new("L", (3, 3), 128) + # Size 1 should not crash (margin is 0) assert im.filter(ImageFilter.MinFilter(1)).getpixel((1, 1)) == 128 assert im.filter(ImageFilter.MaxFilter(1)).getpixel((1, 1)) == 128 diff --git a/src/_imaging.c b/src/_imaging.c index 3cd762ff5c1..2bb3c9743c4 100644 --- a/src/_imaging.c +++ b/src/_imaging.c @@ -1115,6 +1115,9 @@ _expand_image(ImagingObject *self, PyObject *args) { return NULL; } + if (m == 0) { + return PyImagingNew(ImagingCopy(self->image)); + } return PyImagingNew(ImagingExpand(self->image, m)); }