Skip to content

Don't crash on a malformed HEIC file - #262

Open
eeshsaxena wants to merge 1 commit into
ianare:masterfrom
eeshsaxena:fix/heic-robust-errors
Open

Don't crash on a malformed HEIC file#262
eeshsaxena wants to merge 1 commit into
ianare:masterfrom
eeshsaxena:fix/heic-robust-errors

Conversation

@eeshsaxena

Copy link
Copy Markdown

process_file on a malformed HEIC can escape with an exception it doesn't handle, so the caller crashes instead of getting an empty result the way it does for other unreadable images:

import io, struct, exifread
def box(k, p=b""): return struct.pack(">I", 8 + len(p)) + k + p
ftyp = box(b"ftyp", b"heic" + struct.pack(">I", 0) + b"heic")

exifread.process_file(io.BytesIO(ftyp + struct.pack(">I", 0) + b"meta" + b"\x00" * 4))
# NotImplementedError            (a box with size 0)
exifread.process_file(io.BytesIO(ftyp))
# EOFError                       (a box that runs past the end of the file)

The HEIC reader raises a few things process_file doesn't catch: a bare NotImplementedError for a size-0 box, EOFError from get() at end of file, and BadSize / BoxVersion (which subclass ExifError but not InvalidExif).

This keeps everything inside exif-py's own error hierarchy and handles it in one place:

  • next_box raises BadSize for a size-0 box instead of NotImplementedError.
  • get() raises BadSize on an unexpected end of file instead of EOFError.
  • process_file catches the base ExifError, so ExifNotFound, InvalidExif, BadSize and BoxVersion all yield an empty result.

Valid files are unaffected (the existing suite passes, 32). Added a test with several malformed HEIC inputs. This is separate from the non-ASCII box-type case in #245 (that raises UnicodeDecodeError, addressed in #253).

process_file could raise NotImplementedError (an ISO-BMFF box with size 0),
EOFError (a box running past the end of the file), or BadSize / BoxVersion --
none of which process_file caught, so a malformed HEIC crashed the caller
instead of returning no tags.

- next_box raises BadSize for a size-0 box instead of a bare NotImplementedError.
- get() raises BadSize on an unexpected end of file instead of EOFError.
- process_file catches the base ExifError, so every exif-py parse error
  (ExifNotFound, InvalidExif, BadSize, BoxVersion) yields an empty result.

Added a test with several malformed HEIC inputs.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant