mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-26 18:06:18 +03:00
Restoring bad exif handling
This commit is contained in:
parent
47a963c2a4
commit
5f9fff0215
|
@ -468,55 +468,67 @@ class ImageFileDirectory_v2(collections.MutableMapping):
|
||||||
return b"".join(self._pack("2L", *_limit_rational(frac, 2 ** 30))
|
return b"".join(self._pack("2L", *_limit_rational(frac, 2 ** 30))
|
||||||
for frac in values)
|
for frac in values)
|
||||||
|
|
||||||
|
def _ensure_read(self, fp, size):
|
||||||
|
ret = fp.read(size)
|
||||||
|
if len(ret) != size:
|
||||||
|
raise IOError("Corrupt EXIF data. " +
|
||||||
|
"Expecting to read %d bytes but only got %d. " %
|
||||||
|
(size, len(ret)))
|
||||||
|
return ret
|
||||||
|
|
||||||
def load(self, fp):
|
def load(self, fp):
|
||||||
|
|
||||||
self.reset()
|
self.reset()
|
||||||
self._offset = fp.tell()
|
self._offset = fp.tell()
|
||||||
|
|
||||||
for i in range(self._unpack("H", fp.read(2))[0]):
|
try:
|
||||||
tag, typ, count, data = self._unpack("HHL4s", fp.read(12))
|
for i in range(self._unpack("H", self._ensure_read(fp,2))[0]):
|
||||||
if DEBUG:
|
tag, typ, count, data = self._unpack("HHL4s", self._ensure_read(fp,12))
|
||||||
tagname = TAGS.get(tag, TagInfo()).name
|
|
||||||
typname = TYPES.get(typ, "unknown")
|
|
||||||
print("tag: %s (%d) - type: %s (%d)" %
|
|
||||||
(tagname, tag, typname, typ), end=" ")
|
|
||||||
|
|
||||||
try:
|
|
||||||
unit_size, handler = self._load_dispatch[typ]
|
|
||||||
except KeyError:
|
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
print("- unsupported type", typ)
|
tagname = TAGS.get(tag, TagInfo()).name
|
||||||
continue # ignore unsupported type
|
typname = TYPES.get(typ, "unknown")
|
||||||
size = count * unit_size
|
print("tag: %s (%d) - type: %s (%d)" %
|
||||||
if size > 4:
|
(tagname, tag, typname, typ), end=" ")
|
||||||
here = fp.tell()
|
|
||||||
offset, = self._unpack("L", data)
|
|
||||||
if DEBUG:
|
|
||||||
print("Tag Location: %s - Data Location: %s" %
|
|
||||||
(here, offset), end=" ")
|
|
||||||
fp.seek(offset)
|
|
||||||
data = ImageFile._safe_read(fp, size)
|
|
||||||
fp.seek(here)
|
|
||||||
else:
|
|
||||||
data = data[:size]
|
|
||||||
|
|
||||||
if len(data) != size:
|
try:
|
||||||
warnings.warn("Possibly corrupt EXIF data. "
|
unit_size, handler = self._load_dispatch[typ]
|
||||||
"Expecting to read %d bytes but only got %d. "
|
except KeyError:
|
||||||
"Skipping tag %s" % (size, len(data), tag))
|
if DEBUG:
|
||||||
continue
|
print("- unsupported type", typ)
|
||||||
|
continue # ignore unsupported type
|
||||||
self._tagdata[tag] = data
|
size = count * unit_size
|
||||||
self.tagtype[tag] = typ
|
if size > 4:
|
||||||
|
here = fp.tell()
|
||||||
if DEBUG:
|
offset, = self._unpack("L", data)
|
||||||
if size > 32:
|
if DEBUG:
|
||||||
print("- value: <table: %d bytes>" % size)
|
print("Tag Location: %s - Data Location: %s" %
|
||||||
|
(here, offset), end=" ")
|
||||||
|
fp.seek(offset)
|
||||||
|
data = ImageFile._safe_read(fp, size)
|
||||||
|
fp.seek(here)
|
||||||
else:
|
else:
|
||||||
print("- value:", self[tag])
|
data = data[:size]
|
||||||
|
|
||||||
self.next, = self._unpack("L", fp.read(4))
|
if len(data) != size:
|
||||||
|
warnings.warn("Possibly corrupt EXIF data. "
|
||||||
|
"Expecting to read %d bytes but only got %d. "
|
||||||
|
"Skipping tag %s" % (size, len(data), tag))
|
||||||
|
continue
|
||||||
|
|
||||||
|
self._tagdata[tag] = data
|
||||||
|
self.tagtype[tag] = typ
|
||||||
|
|
||||||
|
if DEBUG:
|
||||||
|
if size > 32:
|
||||||
|
print("- value: <table: %d bytes>" % size)
|
||||||
|
else:
|
||||||
|
print("- value:", self[tag])
|
||||||
|
|
||||||
|
self.next, = self._unpack("L", self._ensure_read(fp,4))
|
||||||
|
except IOError as msg:
|
||||||
|
warnings.warn(str(msg))
|
||||||
|
return
|
||||||
|
|
||||||
def save(self, fp):
|
def save(self, fp):
|
||||||
|
|
||||||
if fp.tell() == 0: # skip TIFF header on subsequent pages
|
if fp.tell() == 0: # skip TIFF header on subsequent pages
|
||||||
|
|
|
@ -99,9 +99,11 @@ class TestFileTiff(PillowTestCase):
|
||||||
lambda: TiffImagePlugin.TiffImageFile(invalid_file))
|
lambda: TiffImagePlugin.TiffImageFile(invalid_file))
|
||||||
|
|
||||||
def test_bad_exif(self):
|
def test_bad_exif(self):
|
||||||
image = Image.open('Tests/images/hopper_bad_exif.jpg')
|
try:
|
||||||
image._getexif()
|
Image.open('Tests/images/hopper_bad_exif.jpg')._getexif()
|
||||||
self.assertRaises(Exception, image._getexif)
|
except struct.error:
|
||||||
|
self.fail(
|
||||||
|
"Bad EXIF data passed incorrect values to _binary unpack")
|
||||||
|
|
||||||
def test_save_unsupported_mode(self):
|
def test_save_unsupported_mode(self):
|
||||||
im = hopper("HSV")
|
im = hopper("HSV")
|
||||||
|
|
Loading…
Reference in New Issue
Block a user