mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-01-24 08:14:10 +03:00
Read textual chunks located after IDAT chunks
This commit is contained in:
parent
95d80a7e5d
commit
22837c37e2
|
@ -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):
|
||||||
|
|
|
@ -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