From 8437d98f7fa9049f89aa501213f2e86f14dc07a7 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Wed, 28 Jun 2023 11:43:05 +1000 Subject: [PATCH] Limit size even if one dimension is zero --- Tests/images/zero_width.gif | Bin 0 -> 44 bytes Tests/test_decompression_bomb.py | 9 +++++++++ src/PIL/Image.py | 2 +- src/_imagingft.c | 2 +- 4 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 Tests/images/zero_width.gif diff --git a/Tests/images/zero_width.gif b/Tests/images/zero_width.gif new file mode 100644 index 0000000000000000000000000000000000000000..da6823b60bb104bfd6969a93d71a0b8e245d836e GIT binary patch literal 44 pcmZ?wbhEHbWMEKW_{huv1pk5PKM?&_{K;|>B%lKk)MRDo2LK=z42A#z literal 0 HcmV?d00001 diff --git a/Tests/test_decompression_bomb.py b/Tests/test_decompression_bomb.py index 4fd02449c..87681a0b5 100644 --- a/Tests/test_decompression_bomb.py +++ b/Tests/test_decompression_bomb.py @@ -64,6 +64,15 @@ class TestDecompressionBomb: with pytest.raises(Image.DecompressionBombError): im.seek(1) + def test_exception_gif_zero_width(self): + # Set limit to trigger exception on the test file + Image.MAX_IMAGE_PIXELS = 4 * 64 * 128 + assert Image.MAX_IMAGE_PIXELS == 4 * 64 * 128 + + with pytest.raises(Image.DecompressionBombError): + with Image.open("Tests/images/zero_width.gif"): + pass + def test_exception_bmp(self): with pytest.raises(Image.DecompressionBombError): with Image.open("Tests/images/bmp/b/reallybig.bmp"): diff --git a/src/PIL/Image.py b/src/PIL/Image.py index 97f3f4926..400edcc5b 100644 --- a/src/PIL/Image.py +++ b/src/PIL/Image.py @@ -3141,7 +3141,7 @@ def _decompression_bomb_check(size): if MAX_IMAGE_PIXELS is None: return - pixels = size[0] * size[1] + pixels = max(1, size[0]) * max(1, size[1]) if pixels > 2 * MAX_IMAGE_PIXELS: msg = ( diff --git a/src/_imagingft.c b/src/_imagingft.c index 6cee021d4..fd3255244 100644 --- a/src/_imagingft.c +++ b/src/_imagingft.c @@ -880,7 +880,7 @@ font_render(FontObject *self, PyObject *args) { width += stroke_width * 2 + ceil(x_start); height += stroke_width * 2 + ceil(y_start); if (max_image_pixels != Py_None) { - if ((long long)width * height > PyLong_AsLongLong(max_image_pixels) * 2) { + if ((long long)(width > 1 ? width : 1) * (height > 1 ? height : 1) > PyLong_AsLongLong(max_image_pixels) * 2) { PyMem_Del(glyph_info); return Py_BuildValue("O(ii)(ii)", Py_None, width, height, 0, 0); }