Skip to content

Commit

Permalink
Fix Memory DOS in Icns, Ico and Blp Image Plugins
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
wiredfool authored and radarhere committed Mar 6, 2021
1 parent 886ad5a commit 756fff3
Show file tree
Hide file tree
Showing 5 changed files with 10 additions and 0 deletions.
Binary file not shown.
6 changes: 6 additions & 0 deletions Tests/test_file_icns.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,3 +139,9 @@ def test_not_an_icns_file():
with io.BytesIO(b"invalid\n") as fp:
with pytest.raises(SyntaxError):
IcnsImagePlugin.IcnsFile(fp)


def test_icns_decompression_bomb():
with pytest.raises(Image.DecompressionBombError):
im = Image.open('Tests/images/oom-8ed3316a4109213ca96fb8a256a0bfefdece1461.icns')
im.load()
1 change: 1 addition & 0 deletions src/PIL/BlpImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,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
Expand Down
2 changes: 2 additions & 0 deletions src/PIL/IcnsImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,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"
Expand All @@ -121,6 +122,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}
Expand Down
1 change: 1 addition & 0 deletions src/PIL/IcoImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,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)
Expand Down

0 comments on commit 756fff3

Please sign in to comment.