Restricted PNG encoderinfo chunks to valid values when saving

This commit is contained in:
Andrew Murray 2017-01-21 16:57:03 +11:00
parent ded14572a1
commit f0480de118
2 changed files with 20 additions and 3 deletions

View File

@ -715,6 +715,8 @@ def _save(im, fp, filename, chunk=putchunk, check=0):
b'\0', # 11: filter category b'\0', # 11: filter category
b'\0') # 12: interlace flag 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")) icc = im.encoderinfo.get("icc_profile", im.info.get("icc_profile"))
if icc: if icc:
# ICC profile # ICC profile
@ -726,6 +728,18 @@ def _save(im, fp, filename, chunk=putchunk, check=0):
name = b"ICC Profile" name = b"ICC Profile"
data = name + b"\0\0" + zlib.compress(icc) data = name + b"\0\0" + zlib.compress(icc)
chunk(fp, b"iCCP", data) 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": if im.mode == "P":
palette_byte_number = (2 ** bits) * 3 palette_byte_number = (2 ** bits) * 3
@ -773,7 +787,10 @@ def _save(im, fp, filename, chunk=putchunk, check=0):
info = im.encoderinfo.get("pnginfo") info = im.encoderinfo.get("pnginfo")
if info: if info:
chunks = [b"bKGD", b"hIST"]
for cid, data in info.chunks: for cid, data in info.chunks:
if cid in chunks:
chunks.remove(cid)
chunk(fp, cid, data) chunk(fp, cid, data)
ImageFile._save(im, _idat(fp, chunk), ImageFile._save(im, _idat(fp, chunk),

View File

@ -394,8 +394,8 @@ class TestFilePng(PillowTestCase):
self.assertIsInstance(im.info["Text"], str) self.assertIsInstance(im.info["Text"], str)
def test_unicode_text(self): def test_unicode_text(self):
# Check preservation of non-ASCII characters on Python3 # Check preservation of non-ASCII characters on Python 3
# This cannot really be meaningfully tested on Python2, # This cannot really be meaningfully tested on Python 2,
# since it didn't preserve charsets to begin with. # since it didn't preserve charsets to begin with.
def rt_text(value): def rt_text(value):