From dbf40a0124dc7ed8d3585eb7938410297655c381 Mon Sep 17 00:00:00 2001 From: Vytis Banaitis Date: Tue, 20 Aug 2013 15:17:17 +0300 Subject: [PATCH 1/2] Catch truncated zTXt errors. --- PIL/PngImagePlugin.py | 24 +++++++++++++++++------- Tests/test_file_png.py | 22 ++++++++++++++++++++++ 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/PIL/PngImagePlugin.py b/PIL/PngImagePlugin.py index 7ed018878..9e84e11af 100644 --- a/PIL/PngImagePlugin.py +++ b/PIL/PngImagePlugin.py @@ -305,18 +305,28 @@ class PngStream(ChunkStream): # compressed text s = ImageFile._safe_read(self.fp, len) - k, v = s.split(b"\0", 1) - comp_method = i8(v[0]) + try: + k, v = s.split(b"\0", 1) + except ValueError: + k = s; v = b"" + if v: + comp_method = i8(v[0]) + else: + comp_method = 0 if comp_method != 0: raise SyntaxError("Unknown compression method %s in zTXt chunk" % comp_method) import zlib - v = zlib.decompress(v[1:]) + try: + v = zlib.decompress(v[1:]) + except zlib.error: + v = b"" - if bytes is not str: - k = k.decode('latin-1', 'strict') - v = v.decode('latin-1', 'replace') + if k: + if bytes is not str: + k = k.decode('latin-1', 'strict') + v = v.decode('latin-1', 'replace') - self.im_info[k] = self.im_text[k] = v + self.im_info[k] = self.im_text[k] = v return s # -------------------------------------------------------------------- diff --git a/Tests/test_file_png.py b/Tests/test_file_png.py index 4c14c9a64..b5b964de0 100644 --- a/Tests/test_file_png.py +++ b/Tests/test_file_png.py @@ -2,6 +2,7 @@ from tester import * from PIL import Image from PIL import PngImagePlugin +import zlib codecs = dir(Image.core) @@ -99,6 +100,27 @@ def test_bad_text(): im = load(HEAD + chunk(b'tEXt', b'spam\0egg\0') + TAIL) assert_equal(im.info, {'spam': 'egg\x00'}) +def test_bad_ztxt(): + # Test reading malformed zTXt chunks (python-imaging/Pillow#318) + + im = load(HEAD + chunk(b'zTXt') + TAIL) + assert_equal(im.info, {}) + + im = load(HEAD + chunk(b'zTXt', b'spam') + TAIL) + assert_equal(im.info, {'spam': ''}) + + im = load(HEAD + chunk(b'zTXt', b'spam\0') + TAIL) + assert_equal(im.info, {'spam': ''}) + + im = load(HEAD + chunk(b'zTXt', b'spam\0\0') + TAIL) + assert_equal(im.info, {'spam': ''}) + + im = load(HEAD + chunk(b'zTXt', b'spam\0\0' + zlib.compress(b'egg')[0]) + TAIL) + assert_equal(im.info, {'spam': ''}) + + im = load(HEAD + chunk(b'zTXt', b'spam\0\0' + zlib.compress(b'egg')) + TAIL) + assert_equal(im.info, {'spam': 'egg'}) + def test_interlace(): file = "Tests/images/pil123p.png" From febfd1e12476cd8ca3d457839acb3ae9acaa4b7c Mon Sep 17 00:00:00 2001 From: Vytis Banaitis Date: Tue, 20 Aug 2013 17:09:22 +0300 Subject: [PATCH 2/2] Python3 fix. --- Tests/test_file_png.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/test_file_png.py b/Tests/test_file_png.py index b5b964de0..067ea5812 100644 --- a/Tests/test_file_png.py +++ b/Tests/test_file_png.py @@ -115,7 +115,7 @@ def test_bad_ztxt(): im = load(HEAD + chunk(b'zTXt', b'spam\0\0') + TAIL) assert_equal(im.info, {'spam': ''}) - im = load(HEAD + chunk(b'zTXt', b'spam\0\0' + zlib.compress(b'egg')[0]) + TAIL) + im = load(HEAD + chunk(b'zTXt', b'spam\0\0' + zlib.compress(b'egg')[:1]) + TAIL) assert_equal(im.info, {'spam': ''}) im = load(HEAD + chunk(b'zTXt', b'spam\0\0' + zlib.compress(b'egg')) + TAIL)