diff --git a/PIL/ImageFile.py b/PIL/ImageFile.py index d892ba584..597e41783 100644 --- a/PIL/ImageFile.py +++ b/PIL/ImageFile.py @@ -33,7 +33,7 @@ import io import logging import os import sys -# import traceback +import struct logger = logging.getLogger(__name__) @@ -101,7 +101,8 @@ class ImageFile(Image.Image): except (IndexError, # end of data TypeError, # end of data (ord) KeyError, # unsupported mode - EOFError) as v: # got header but not the first frame + EOFError, # got header but not the first frame + struct.error) as v: logger.exception("%s") raise SyntaxError(v) @@ -204,11 +205,11 @@ class ImageFile(Image.Image): while True: try: s = read(self.decodermaxblock) - except IndexError as ie: # truncated png/gif + except (IndexError, struct.error): # truncated png/gif if LOAD_TRUNCATED_IMAGES: break else: - raise IndexError(ie) + raise IOError("image file is truncated") if not s and not d.handles_eof: # truncated jpeg self.tile = [] diff --git a/Tests/images/truncated_image.png b/Tests/images/truncated_image.png new file mode 100644 index 000000000..cb32dc986 Binary files /dev/null and b/Tests/images/truncated_image.png differ diff --git a/Tests/test_imagefile.py b/Tests/test_imagefile.py index fbd10d47b..857df1441 100644 --- a/Tests/test_imagefile.py +++ b/Tests/test_imagefile.py @@ -79,12 +79,11 @@ class TestImageFile(PillowTestCase): self.assertEqual((48, 48), p.image.size) def test_safeblock(self): - - im1 = hopper() - if "zip_encoder" not in codecs: self.skipTest("PNG (zlib) encoder not available") + im1 = hopper() + try: ImageFile.SAFEBLOCK = 1 im2 = fromstring(tostring(im1, "PNG")) @@ -96,6 +95,25 @@ class TestImageFile(PillowTestCase): def test_raise_ioerror(self): self.assertRaises(IOError, lambda: ImageFile.raise_ioerror(1)) + def test_truncated_with_errors(self): + if "zip_encoder" not in codecs: + self.skipTest("PNG (zlib) encoder not available") + + im = Image.open("Tests/images/truncated_image.png") + with self.assertRaises(IOError): + im.load() + + def test_truncated_without_errors(self): + if "zip_encoder" not in codecs: + self.skipTest("PNG (zlib) encoder not available") + + im = Image.open("Tests/images/truncated_image.png") + + ImageFile.LOAD_TRUNCATED_IMAGES = True + try: + im.load() + finally: + ImageFile.LOAD_TRUNCATED_IMAGES = False if __name__ == '__main__': unittest.main()