mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-11-10 19:56:47 +03:00
Merge pull request #3506 from radarhere/png
Read textual chunks located after IDAT chunks for PNG
This commit is contained in:
commit
a43b8bac1e
|
@ -557,6 +557,28 @@ class TestFilePng(PillowTestCase):
|
|||
chunks = PngImagePlugin.getchunks(im)
|
||||
self.assertEqual(len(chunks), 3)
|
||||
|
||||
def test_textual_chunks_after_idat(self):
|
||||
im = Image.open("Tests/images/hopper.png")
|
||||
self.assertIn('comment', im.text.keys())
|
||||
for k, v in {
|
||||
'date:create': '2014-09-04T09:37:08+03:00',
|
||||
'date:modify': '2014-09-04T09:37:08+03:00',
|
||||
}.items():
|
||||
self.assertEqual(im.text[k], v)
|
||||
|
||||
# Raises a SyntaxError in load_end
|
||||
im = Image.open("Tests/images/broken_data_stream.png")
|
||||
with self.assertRaises(IOError):
|
||||
self.assertIsInstance(im.text, dict)
|
||||
|
||||
# Raises a UnicodeDecodeError in load_end
|
||||
im = Image.open("Tests/images/truncated_image.png")
|
||||
# The file is truncated
|
||||
self.assertRaises(IOError, lambda: im.text)
|
||||
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
||||
self.assertIsInstance(im.text, dict)
|
||||
ImageFile.LOAD_TRUNCATED_IMAGES = False
|
||||
|
||||
|
||||
@unittest.skipIf(sys.platform.startswith('win32'), "requires Unix or macOS")
|
||||
class TestTruncatedPngPLeaks(PillowLeakTestCase):
|
||||
|
|
|
@ -482,7 +482,7 @@ The :py:meth:`~PIL.Image.Image.open` method sets the following
|
|||
|
||||
This key is omitted if the image is not a transparent palette image.
|
||||
|
||||
``Open`` also sets ``Image.text`` to a list of the values of the
|
||||
``Open`` also sets ``Image.text`` to a dictionary of the values of the
|
||||
``tEXt``, ``zTXt``, and ``iTXt`` chunks of the PNG image. Individual
|
||||
compressed chunks are limited to a decompressed size of
|
||||
``PngImagePlugin.MAX_TEXT_CHUNK``, by default 1MB, to prevent
|
||||
|
|
|
@ -579,7 +579,7 @@ class PngImageFile(ImageFile.ImageFile):
|
|||
self.mode = self.png.im_mode
|
||||
self._size = self.png.im_size
|
||||
self.info = self.png.im_info
|
||||
self.text = self.png.im_text # experimental
|
||||
self._text = None
|
||||
self.tile = self.png.im_tile
|
||||
|
||||
if self.png.im_palette:
|
||||
|
@ -588,6 +588,15 @@ class PngImageFile(ImageFile.ImageFile):
|
|||
|
||||
self.__idat = length # used by load_read()
|
||||
|
||||
@property
|
||||
def text(self):
|
||||
# experimental
|
||||
if self._text is None:
|
||||
# iTxt, tEXt and zTXt chunks may appear at the end of the file
|
||||
# So load the file to ensure that they are read
|
||||
self.load()
|
||||
return self._text
|
||||
|
||||
def verify(self):
|
||||
"Verify PNG file"
|
||||
|
||||
|
@ -640,7 +649,22 @@ class PngImageFile(ImageFile.ImageFile):
|
|||
|
||||
def load_end(self):
|
||||
"internal: finished reading image data"
|
||||
while True:
|
||||
self.fp.read(4) # CRC
|
||||
|
||||
try:
|
||||
cid, pos, length = self.png.read()
|
||||
except (struct.error, SyntaxError):
|
||||
break
|
||||
|
||||
if cid == b"IEND":
|
||||
break
|
||||
|
||||
try:
|
||||
self.png.call(cid, pos, length)
|
||||
except UnicodeDecodeError:
|
||||
break
|
||||
self._text = self.png.im_text
|
||||
self.png.close()
|
||||
self.png = None
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user