Made Exif handling more resilient. #104

This commit is contained in:
jevans 2013-10-26 18:05:44 -04:00
commit 7e717b5037
3 changed files with 77 additions and 9 deletions

View file

@ -39,9 +39,13 @@ class UUIDExif(object):
if data[0] == 73 and data[1] == 73:
# little endian
self.endian = '<'
else:
elif data[0] == 77 and data[1] == 77:
# big endian
self.endian = '>'
else:
msg = "Bad byte order indication: {0}".format(read_buffer[6:8])
raise RuntimeError(msg)
offset = data[3]
# This is the 'Exif Image' portion.

View file

@ -19,6 +19,7 @@ import os
import pprint
import struct
import sys
import traceback
import uuid
import warnings
import xml.etree.cElementTree as ET
@ -2078,15 +2079,23 @@ class UUIDBox(Jp2kBox):
Jp2kBox.__init__(self, box_id='uuid', longname='UUID')
self.uuid = the_uuid
if the_uuid == uuid.UUID('be7acfcb-97a9-42e8-9c71-999491e3afac'):
self.data = _uuid_io.UUIDXMP(raw_data)
self._type = 'XMP'
elif the_uuid.bytes == b'JpgTiffExif->JP2':
self.data = _uuid_io.UUIDExif(raw_data)
self._type = 'Exif'
else:
try:
if the_uuid == uuid.UUID('be7acfcb-97a9-42e8-9c71-999491e3afac'):
self.data = _uuid_io.UUIDXMP(raw_data)
self._type = 'XMP'
elif the_uuid.bytes == b'JpgTiffExif->JP2':
self.data = _uuid_io.UUIDExif(raw_data)
self._type = 'Exif'
else:
self.data = _uuid_io.UUIDGeneric(raw_data)
self._type = 'unknown'
except Exception as err:
# In case of any exception, create the generic UUID.
self.data = _uuid_io.UUIDGeneric(raw_data)
self._type = 'unknown'
msg = "Error encountered during UUID processing, "
msg += "the UUID will be treated as generic.\n\n{0}"
warnings.warn(msg.format(traceback.format_exc()))
self.raw_data = raw_data

View file

@ -63,7 +63,7 @@ class TestUUIDExif(unittest.TestCase):
xbuffer = struct.pack('<BBHI', 73, 73, 42, 8)
tfile.write(xbuffer)
# We will write just a single file.
# We will write just a single tag.
tfile.write(struct.pack('<H', 1))
# The "Make" tag is tag no. 271. Corrupt it to 171.
@ -73,6 +73,61 @@ class TestUUIDExif(unittest.TestCase):
with self.assertWarns(UserWarning):
j = glymur.Jp2k(tfile.name)
@unittest.skipIf(sys.hexversion < 0x03000000, "Requires assertWarns, 3.2+")
def test_bad_tag_datatype(self):
"""Only certain datatypes are allowable"""
with tempfile.NamedTemporaryFile(suffix='.jp2', mode='wb') as tfile:
with open(self.jp2file, 'rb') as ifptr:
tfile.write(ifptr.read())
# Write L, T, UUID identifier.
tfile.write(struct.pack('>I4s', 52, b'uuid'))
tfile.write(b'JpgTiffExif->JP2')
tfile.write(b'Exif\x00\x00')
xbuffer = struct.pack('<BBHI', 73, 73, 42, 8)
tfile.write(xbuffer)
# We will write just a single tag.
tfile.write(struct.pack('<H', 1))
# 2000 is not an allowable TIFF datatype.
tfile.write(struct.pack('<HHI4s', 271, 2000, 3, b'HTC\x00'))
tfile.flush()
with self.assertWarns(UserWarning):
j = glymur.Jp2k(tfile.name)
self.assertEqual(j.box[-1].box_id, 'uuid')
@unittest.skipIf(sys.hexversion < 0x03000000, "Requires assertWarns, 3.2+")
def test_bad_tiff_header_byte_order_indication(self):
"""Only b'II' and b'MM' are allowed."""
with tempfile.NamedTemporaryFile(suffix='.jp2', mode='wb') as tfile:
with open(self.jp2file, 'rb') as ifptr:
tfile.write(ifptr.read())
# Write L, T, UUID identifier.
tfile.write(struct.pack('>I4s', 52, b'uuid'))
tfile.write(b'JpgTiffExif->JP2')
tfile.write(b'Exif\x00\x00')
xbuffer = struct.pack('<BBHI', 74, 73, 42, 8)
tfile.write(xbuffer)
# We will write just a single tag.
tfile.write(struct.pack('<H', 1))
# 271 is the Make.
tfile.write(struct.pack('<HHI4s', 271, 2, 3, b'HTC\x00'))
tfile.flush()
with self.assertWarns(UserWarning):
j = glymur.Jp2k(tfile.name)
self.assertEqual(j.box[-1].box_id, 'uuid')
if __name__ == "__main__":
unittest.main()