FrameAware.apply_to_frames iterates range(self.im.n_frames) and calls self.im.seek(i) with no error handling.
I just stumbled over this while uploading JPGs from a DJI Drone to a django-cms project with filer. Seems they create MPO JPEGs, whose embedded preview frame have malformed offsets and make PIL raise ValueError("No data found for frame").
So a single bad secondary frame currently kills the entire thumbnail pipeline, even though the primary frame would render correctly.
Suggested Fix:
Tolerate per-frame failures and continue with whatever frames were successfully read (at minimum frame 0):
def apply_to_frames(self, method, *args, **kwargs):
new_frames = []
for i in range(self.im.n_frames):
try:
self.im.seek(i)
new_frames.append(method(*args, **kwargs))
except (ValueError, EOFError, OSError):
break
if not new_frames:
self.im.seek(0)
new_frames.append(method(*args, **kwargs))
...
Behavior for valid multi-frame inputs (animated GIF/WebP) is unchanged; malformed MPOs degrade to a clean single-frame thumbnail instead of crashing.
FrameAware.apply_to_framesiteratesrange(self.im.n_frames)and callsself.im.seek(i)with no error handling.I just stumbled over this while uploading JPGs from a DJI Drone to a django-cms project with filer. Seems they create MPO JPEGs, whose embedded preview frame have malformed offsets and make PIL raise
ValueError("No data found for frame").So a single bad secondary frame currently kills the entire thumbnail pipeline, even though the primary frame would render correctly.
Suggested Fix:
Tolerate per-frame failures and continue with whatever frames were successfully read (at minimum frame 0):
Behavior for valid multi-frame inputs (animated GIF/WebP) is unchanged; malformed MPOs degrade to a clean single-frame thumbnail instead of crashing.