File 019-Fix-Memory-DOS-in-BLP-ICNS-and-ICO-Image-Plugins.patch of Package python-Pillow
From 756fff33128a0b643d10518a26ad04b726dd8973 Mon Sep 17 00:00:00 2001
From: Eric Soroos <eric-github@soroos.net>
Date: Wed, 24 Feb 2021 23:27:07 +0100
Subject: [PATCH] Fix Memory DOS in Icns, Ico and Blp Image Plugins
Some container plugins that could contain images of other formats,
such as the ICNS format, did not properly check the reported size of
the contained image. These images could cause arbitrariliy large
memory allocations.
This is fixed for all locations where individual *ImageFile classes
are created without going through the usual Image.open method.
---
...d3316a4109213ca96fb8a256a0bfefdece1461.icns | Bin 0 -> 240915 bytes
Tests/test_file_icns.py | 6 ++++++
src/PIL/BlpImagePlugin.py | 1 +
src/PIL/IcnsImagePlugin.py | 2 ++
src/PIL/IcoImagePlugin.py | 1 +
5 files changed, 10 insertions(+)
create mode 100644 Tests/images/oom-8ed3316a4109213ca96fb8a256a0bfefdece1461.icns
diff --git a/Tests/test_file_icns.py b/Tests/test_file_icns.py
index a3d502d429..ce89f01582 100644
--- a/Tests/test_file_icns.py
+++ b/Tests/test_file_icns.py
@@ -114,6 +114,12 @@ def test_not_an_icns_file():
with io.BytesIO(b'invalid\n') as fp:
self.assertRaises(SyntaxError,
IcnsImagePlugin.IcnsFile, fp)
+
+# disabled because test image uses JPEG2000 which is not enabled for this package
+# def test_icns_decompression_bomb(self):
+# with self.assertRaises(Image.DecompressionBombError):
+# im = Image.open('Tests/images/oom-8ed3316a4109213ca96fb8a256a0bfefdece1461.icns')
+# im.load()
if __name__ == '__main__':
diff --git a/src/PIL/BlpImagePlugin.py b/src/PIL/BlpImagePlugin.py
index d5d7c0e053..88aae80eb9 100644
--- a/src/PIL/BlpImagePlugin.py
+++ b/src/PIL/BlpImagePlugin.py
@@ -362,6 +362,7 @@ def _decode_jpeg_stream(self):
data = jpeg_header + data
data = BytesIO(data)
image = JpegImageFile(data)
+ Image._decompression_bomb_check(image.size)
self.tile = image.tile # :/
self.fd = image.fp
self.mode = image.mode
diff --git a/src/PIL/IcnsImagePlugin.py b/src/PIL/IcnsImagePlugin.py
index 2a63d75cb2..ca6a0adad4 100644
--- a/src/PIL/IcnsImagePlugin.py
+++ b/src/PIL/IcnsImagePlugin.py
@@ -110,6 +110,7 @@ def read_png_or_jpeg2000(fobj, start_length, size):
if sig[:8] == b'\x89PNG\x0d\x0a\x1a\x0a':
fobj.seek(start)
im = PngImagePlugin.PngImageFile(fobj)
+ Image._decompression_bomb_check(im.size)
return {"RGBA": im}
elif sig[:4] == b'\xff\x4f\xff\x51' \
or sig[:4] == b'\x0d\x0a\x87\x0a' \
@@ -122,6 +123,7 @@ def read_png_or_jpeg2000(fobj, start_length, size):
jp2kstream = fobj.read(length)
f = io.BytesIO(jp2kstream)
im = Jpeg2KImagePlugin.Jpeg2KImageFile(f)
+ Image._decompression_bomb_check(im.size)
if im.mode != 'RGBA':
im = im.convert('RGBA')
return {"RGBA": im}
diff --git a/src/PIL/IcoImagePlugin.py b/src/PIL/IcoImagePlugin.py
index e1bfa7a598..5634bf8e91 100644
--- a/src/PIL/IcoImagePlugin.py
+++ b/src/PIL/IcoImagePlugin.py
@@ -164,6 +164,7 @@ def frame(self, idx):
if data[:8] == PngImagePlugin._MAGIC:
# png frame
im = PngImagePlugin.PngImageFile(self.buf)
+ Image._decompression_bomb_check(im.size)
else:
# XOR + AND mask bmp frame
im = BmpImagePlugin.DibImageFile(self.buf)