From 9acce90340d3ae2082c10abd8b5a4d404ab53a43 Mon Sep 17 00:00:00 2001 From: Wynn Wilkes Date: Wed, 5 Dec 2018 11:08:11 -0700 Subject: [PATCH] Fix for dumping exif data loaded from images that contain a Gps VersionID tag - This puts in python2 specific conditional check into _value_to_bytes() that will make sure a raw_value of type str uses struct.unpack to generate int's to send to the _pack_byte() function, otherwise it crashes trying to create ints from the chars in the str object. This crash was found when loading exif data from a picture shot with a Canon PowerShot SX50 HS (according to the exif data), and it's Gps/VersionID value was 2.3.0.0 but at run time was loaded as '\x02\x03\x00\x00'. This probably needs an equivalent fix for Python 3. --- piexif/_dump.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/piexif/_dump.py b/piexif/_dump.py index 4617a69..29a52f7 100644 --- a/piexif/_dump.py +++ b/piexif/_dump.py @@ -1,6 +1,7 @@ import copy import numbers import struct +import sys from ._common import * from ._exif import * @@ -8,6 +9,8 @@ TIFF_HEADER_LENGTH = 8 +_PY2 = sys.version_info[0] == 2 + def dump(exif_dict_original): """ @@ -190,8 +193,17 @@ def _value_to_bytes(raw_value, value_type, offset): if value_type == TYPES.Byte: length = len(raw_value) if length <= 4: - value_str = (_pack_byte(*raw_value) + - b"\x00" * (4 - length)) + if _PY2: + if isinstance(raw_value, str): + raw_value_ints = struct.unpack('<' + ('B' * length), raw_value) + else: + # assumes that it's a tuple/list of ints already + raw_value_ints = raw_value + else: + # TODO: should we check for a bytes object in this case on python3? + raw_value_ints = raw_value + value_str = (_pack_byte(*raw_value_ints) + + b"\x00" * (4 - length)) else: value_str = struct.pack(">I", offset) four_bytes_over = _pack_byte(*raw_value)