Skip to content

Commit 5c0fa96

Browse files
authored
Resolves #45 (#48)
Invalid EXIF support
1 parent 513d48e commit 5c0fa96

File tree

2 files changed

+39
-20
lines changed

2 files changed

+39
-20
lines changed

pillow_heif/misc.py

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -34,25 +34,28 @@ def set_orientation(info: dict, orientation: int = 1) -> Union[int, None]:
3434

3535
original_orientation = None
3636
if info.get("exif", None):
37-
tif_tag = info["exif"]
38-
if tif_tag.startswith(b"Exif\x00\x00"):
39-
tif_tag = tif_tag[6:]
40-
endian_mark = "<" if tif_tag[0:2] == b"\x49\x49" else ">"
41-
pointer = unpack(endian_mark + "L", tif_tag[4:8])[0]
42-
tag_count = unpack(endian_mark + "H", tif_tag[pointer : pointer + 2])[0]
43-
offset = pointer + 2
44-
for tag_n in range(tag_count):
45-
pointer = offset + 12 * tag_n
46-
if unpack(endian_mark + "H", tif_tag[pointer : pointer + 2])[0] != 274:
47-
continue
48-
value = tif_tag[pointer + 8 : pointer + 12]
49-
_original_orientation = unpack(endian_mark + "H", value[0:2])[0]
50-
if _original_orientation != 1:
51-
original_orientation = _original_orientation
52-
p_value = 6 + pointer + 8
53-
new_orientation = pack(endian_mark + "H", orientation)
54-
info["exif"] = info["exif"][:p_value] + new_orientation + info["exif"][p_value + 2 :]
55-
break
37+
try:
38+
tif_tag = info["exif"]
39+
if tif_tag.startswith(b"Exif\x00\x00"):
40+
tif_tag = tif_tag[6:]
41+
endian_mark = "<" if tif_tag[0:2] == b"\x49\x49" else ">"
42+
pointer = unpack(endian_mark + "L", tif_tag[4:8])[0]
43+
tag_count = unpack(endian_mark + "H", tif_tag[pointer : pointer + 2])[0]
44+
offset = pointer + 2
45+
for tag_n in range(tag_count):
46+
pointer = offset + 12 * tag_n
47+
if unpack(endian_mark + "H", tif_tag[pointer : pointer + 2])[0] != 274:
48+
continue
49+
value = tif_tag[pointer + 8 : pointer + 12]
50+
_original_orientation = unpack(endian_mark + "H", value[0:2])[0]
51+
if _original_orientation != 1:
52+
original_orientation = _original_orientation
53+
p_value = 6 + pointer + 8
54+
new_orientation = pack(endian_mark + "H", orientation)
55+
info["exif"] = info["exif"][:p_value] + new_orientation + info["exif"][p_value + 2 :]
56+
break
57+
except Exception: # noqa # pylint: disable=broad-except
58+
pass
5659
if info.get("xmp", None):
5760
xmp_data = info["xmp"].decode("utf-8")
5861
match = re.search(r'tiff:Orientation(="|>)([0-9])', xmp_data)

tests/metadata_exif_test.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,17 @@ def pil_image_with_exif():
4040
exif = im.getexif() # noqa
4141
assert exif[0x010E] == exif_desc_value
4242
out_im_heif = BytesIO()
43-
im.save(out_im_heif, format=save_format)
43+
im.save(out_im_heif, format=save_format) # saving to HEIF(AVIF)
4444
im_heif = Image.open(out_im_heif)
4545
assert im_heif.info["exif"]
4646
assert isinstance(im_heif.info["exif"], bytes)
4747
exif = im_heif.getexif() # noqa
4848
assert exif[0x010E] == exif_desc_value
49+
out_im = BytesIO()
50+
im_heif.save(out_im, format=im_format, exif=im_heif.getexif()) # saving back to original format
51+
im = Image.open(out_im)
52+
exif = im.getexif() # noqa
53+
assert exif[0x010E] == exif_desc_value
4954

5055

5156
@pytest.mark.skipif(not helpers.hevc_enc(), reason="Requires HEIF encoder.")
@@ -159,3 +164,14 @@ def test_heif_multi_frame_exif_add_remove():
159164
im_heif_no_exif = pillow_heif.open_heif(out_heif_no_exif)
160165
assert "exif" not in im_heif_no_exif[0].info or im_heif_no_exif[0].info["exif"] is None
161166
assert "exif" not in im_heif_no_exif[1].info or im_heif_no_exif[1].info["exif"] is None
167+
168+
169+
@pytest.mark.skipif(not helpers.hevc_enc(), reason="Requires HEIF encoder.")
170+
def test_corrupted_exif():
171+
exif_data = b"This_is_not_valid_EXIF_data"
172+
out_im = BytesIO()
173+
helpers.gradient_rgb().save(out_im, format="HEIF", exif=exif_data)
174+
im = Image.open(out_im)
175+
with pytest.raises(SyntaxError):
176+
im.getexif()
177+
assert im.info["exif"] == exif_data

0 commit comments

Comments
 (0)