mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-01-26 09:14:27 +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)
|
chunks = PngImagePlugin.getchunks(im)
|
||||||
self.assertEqual(len(chunks), 3)
|
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")
|
@unittest.skipIf(sys.platform.startswith('win32'), "requires Unix or macOS")
|
||||||
class TestTruncatedPngPLeaks(PillowLeakTestCase):
|
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.
|
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
|
``tEXt``, ``zTXt``, and ``iTXt`` chunks of the PNG image. Individual
|
||||||
compressed chunks are limited to a decompressed size of
|
compressed chunks are limited to a decompressed size of
|
||||||
``PngImagePlugin.MAX_TEXT_CHUNK``, by default 1MB, to prevent
|
``PngImagePlugin.MAX_TEXT_CHUNK``, by default 1MB, to prevent
|
||||||
|
|
|
@ -579,7 +579,7 @@ class PngImageFile(ImageFile.ImageFile):
|
||||||
self.mode = self.png.im_mode
|
self.mode = self.png.im_mode
|
||||||
self._size = self.png.im_size
|
self._size = self.png.im_size
|
||||||
self.info = self.png.im_info
|
self.info = self.png.im_info
|
||||||
self.text = self.png.im_text # experimental
|
self._text = None
|
||||||
self.tile = self.png.im_tile
|
self.tile = self.png.im_tile
|
||||||
|
|
||||||
if self.png.im_palette:
|
if self.png.im_palette:
|
||||||
|
@ -588,6 +588,15 @@ class PngImageFile(ImageFile.ImageFile):
|
||||||
|
|
||||||
self.__idat = length # used by load_read()
|
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):
|
def verify(self):
|
||||||
"Verify PNG file"
|
"Verify PNG file"
|
||||||
|
|
||||||
|
@ -640,7 +649,22 @@ class PngImageFile(ImageFile.ImageFile):
|
||||||
|
|
||||||
def load_end(self):
|
def load_end(self):
|
||||||
"internal: finished reading image data"
|
"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.close()
|
||||||
self.png = None
|
self.png = None
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user