Ability to skip crc checks for ancillary chunks

This commit is contained in:
Konstantin Kopachev 2016-06-29 12:24:37 -07:00
parent 30eced6286
commit c3b970f046
No known key found for this signature in database
GPG Key ID: CECF757E656F4F62
2 changed files with 36 additions and 0 deletions

View File

@ -138,6 +138,12 @@ class ChunkStream(object):
def crc(self, cid, data): def crc(self, cid, data):
"Read and verify checksum" "Read and verify checksum"
# Skip CRC checks for ancillary chunks if allowed to load truncated images
# 5th byte of first char is 1 [specs, section 5.4]
if ImageFile.LOAD_TRUNCATED_IMAGES and (ord(cid[0]) >> 5 & 1):
self.crc_skip(cid, data)
return
try: try:
crc1 = Image.core.crc32(data, Image.core.crc32(cid)) crc1 = Image.core.crc32(data, Image.core.crc32(cid))
crc2 = i16(self.fp.read(2)), i16(self.fp.read(2)) crc2 = i16(self.fp.read(2)), i16(self.fp.read(2))

View File

@ -3,6 +3,7 @@ from helper import unittest, PillowTestCase, hopper
from io import BytesIO from io import BytesIO
from PIL import Image from PIL import Image
from PIL import ImageFile
from PIL import PngImagePlugin from PIL import PngImagePlugin
import zlib import zlib
@ -319,6 +320,35 @@ class TestFilePng(PillowTestCase):
self.assertTrue(im.fp is not None) self.assertTrue(im.fp is not None)
self.assertRaises((IOError, SyntaxError), im.verify) self.assertRaises((IOError, SyntaxError), im.verify)
def test_verify_ignores_crc_error(self):
# check ignores crc errors in ancillary chunks
chunk_data = chunk(b'tEXt', b'spam')
broken_crc_chunk_data = chunk_data[:-1] + 'q' # break CRC
image_data = HEAD + broken_crc_chunk_data + TAIL
self.assertRaises(SyntaxError,
lambda: PngImagePlugin.PngImageFile(BytesIO(image_data)))
ImageFile.LOAD_TRUNCATED_IMAGES = True
try:
im = load(image_data)
self.assertTrue(im is not None)
finally:
ImageFile.LOAD_TRUNCATED_IMAGES = False
def test_verify_not_ignores_crc_error_in_required_chunk(self):
# check does not ignore crc errors in required chunks
image_data = MAGIC + IHDR[:-1] + 'q' + TAIL
ImageFile.LOAD_TRUNCATED_IMAGES = True
try:
self.assertRaises(SyntaxError,
lambda: PngImagePlugin.PngImageFile(BytesIO(image_data)))
finally:
ImageFile.LOAD_TRUNCATED_IMAGES = False
def test_roundtrip_dpi(self): def test_roundtrip_dpi(self):
# Check dpi roundtripping # Check dpi roundtripping