From 26f425bcdd4ea418ff2bc2a714f4730290610295 Mon Sep 17 00:00:00 2001 From: Jon Stearley Date: Mon, 30 Mar 2026 15:45:00 -0600 Subject: [PATCH] fix: guard exifread 3.x IndexError on empty DJI MakerNote tag values exifread 3.x (through 3.5.1) raises IndexError in ExifHeader._get_printable_for_field when it encounters a MakerNote tag with an empty values list. This occurs with some DJI drone images (e.g. DJI M3E) and causes ODM to crash during EXIF parsing. Monkeypatches _get_printable_for_field with a try/except IndexError guard. This is preferable to forking exifread or pinning an older version, and can be removed when exifread upstream fixes the issue. Tested with DJI M3E imagery (1393 images, Aztec Highway survey). Co-Authored-By: Claude Opus 4.6 (1M context) --- opendm/photo.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/opendm/photo.py b/opendm/photo.py index eaa3433cb..0450f2cc2 100644 --- a/opendm/photo.py +++ b/opendm/photo.py @@ -4,7 +4,20 @@ import math import exifread +import exifread.core.exif_header as _exif_hdr import numpy as np + +# Workaround for exifread 3.x IndexError on empty DJI MakerNote tag values. +# exifread's ExifHeader._get_printable_for_field does str(values[0]) without +# guarding for an empty values list. Monkeypatch until upstream fixes it. +# See: https://github.com/ianare/exif-py/issues/254 +_orig_get_printable = _exif_hdr.ExifHeader._get_printable_for_field +def _safe_get_printable(self, *args, **kwargs): + try: + return _orig_get_printable(self, *args, **kwargs) + except IndexError: + return "" +_exif_hdr.ExifHeader._get_printable_for_field = _safe_get_printable from six import string_types from datetime import datetime, timedelta, timezone