From f0480de118c36024094801fd98de9513c6ec4785 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Sat, 21 Jan 2017 16:57:03 +1100 Subject: [PATCH] Restricted PNG encoderinfo chunks to valid values when saving --- PIL/PngImagePlugin.py | 19 ++++++++++++++++++- Tests/test_file_png.py | 4 ++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/PIL/PngImagePlugin.py b/PIL/PngImagePlugin.py index 486162a38..a633d4e54 100644 --- a/PIL/PngImagePlugin.py +++ b/PIL/PngImagePlugin.py @@ -715,6 +715,8 @@ def _save(im, fp, filename, chunk=putchunk, check=0): b'\0', # 11: filter category b'\0') # 12: interlace flag + chunks = [b"cHRM", b"gAMA", b"sBIT", b"sRGB", b"tIME"] + icc = im.encoderinfo.get("icc_profile", im.info.get("icc_profile")) if icc: # ICC profile @@ -726,6 +728,18 @@ def _save(im, fp, filename, chunk=putchunk, check=0): name = b"ICC Profile" data = name + b"\0\0" + zlib.compress(icc) chunk(fp, b"iCCP", data) + else: + chunks.remove(b"sRGB") + + info = im.encoderinfo.get("pnginfo") + if info: + chunks_multiple_allowed = [b"sPLT", b"iTXt", b"tEXt", b"zTXt"] + for cid, data in info.chunks: + if cid in chunks: + chunks.remove(cid) + chunk(fp, cid, data) + elif cid in chunks_multiple_allowed: + chunk(fp, cid, data) if im.mode == "P": palette_byte_number = (2 ** bits) * 3 @@ -773,8 +787,11 @@ def _save(im, fp, filename, chunk=putchunk, check=0): info = im.encoderinfo.get("pnginfo") if info: + chunks = [b"bKGD", b"hIST"] for cid, data in info.chunks: - chunk(fp, cid, data) + if cid in chunks: + chunks.remove(cid) + chunk(fp, cid, data) ImageFile._save(im, _idat(fp, chunk), [("zip", (0, 0)+im.size, 0, rawmode)]) diff --git a/Tests/test_file_png.py b/Tests/test_file_png.py index 8af5afe2f..32d6a3acd 100644 --- a/Tests/test_file_png.py +++ b/Tests/test_file_png.py @@ -394,8 +394,8 @@ class TestFilePng(PillowTestCase): self.assertIsInstance(im.info["Text"], str) def test_unicode_text(self): - # Check preservation of non-ASCII characters on Python3 - # This cannot really be meaningfully tested on Python2, + # Check preservation of non-ASCII characters on Python 3 + # This cannot really be meaningfully tested on Python 2, # since it didn't preserve charsets to begin with. def rt_text(value):