Skip to content

TinyEXIF 1.1.0

Choose a tag to compare

@github-actions github-actions released this 23 Aug 06:39

Added

  • HasField() / GetFields() API to tell an absent tag apart from one that is
    legitimately zero, with one FieldID enumerator per data field and
    FieldName() to print it. Purely additive: existing fields, sentinels
    (DBL_MAX, UINT32_MAX) and hasXxx() accessors are unchanged. (#15)
  • GPano_t extended with the rest of the Google spherical-metadata field
    set: PoseHeadingDegrees, ProjectionType, the four cropped/full pano
    pixel dimensions, CroppedAreaLeftPixels, CroppedAreaTopPixels, and
    isEquirectangular(). Based on the approach in PR #27 by @simfeo,
    reimplemented here with the full field set and corpus fixtures.
  • GCamera:MotionPhoto parsing into new HasMotionPhoto, MotionPhotoLength
    and MotionPhotoMime fields, kept separate from the pre-existing
    MicroVideoOffset since the two are not interchangeable; the container is
    only walked when the file actually declares one. Based on PR #27 by
    @simfeo, reworked as described.
  • TINYEXIF_VERSION_STRING / TINYEXIF_VERSION macros, derived from the
    major/minor/patch macros, for downstream feature-gating.
  • A libFuzzer target (BUILD_FUZZER, Clang-only), an ASan+UBSan CI job
    running the full Samples/ corpus under sanitizers, and SECURITY.md
    documenting the disclosure process.
  • LICENSE.easyexif, reproducing easyexif's BSD-2-Clause notice, with
    pointers from LICENSE and README.md noting that portions of this code
    derive from easyexif and remain additionally subject to it.
  • TestSamples.py rewritten from an ad hoc script into a real pass/fail
    regression runner (with a subprocess timeout), now the CI gate for both
    the sanitizer job and this release's parser changes.

Changed

  • GPSAltitudeRef sign handling — parsed values change for ref 1 or 3.
    Some writers (e.g. DroneDeploy) emit an already-negative GPSAltitude and
    still set AltitudeRef = 1; the old code re-negated it, flipping the sign
    back to positive. The magnitude is now taken before negating, and
    AltitudeRef == 3 (negative sea-level reference) is now handled at all —
    it was previously ignored. AltitudeRef 0 and 2 are untouched. Downstream
    consumers of GeoLocation.Altitude should check whether their inputs use
    refs 1 or 3.
  • Version is now single-sourced from TinyEXIF.h; CMakeLists.txt reads it
    from the header's macros and fails the configure step if vcpkg.json's
    version-string disagrees, fixing drift between the two (the header read
    1.0.3 while CMake/vcpkg.json read 1.0.4).

Security

Published as security advisory
GHSA-jqj2-8c2j-gx82
(High). Every issue below is reachable by handing the library a crafted JPEG,
and there is no workaround other than upgrading.

  • Bounds-checked every attacker-controlled buffer read reachable through
    EntryParser::Fetch, ParseTag(), MakerNote parsing, and the EXIF
    segment offset walk, closing a reported crash in Fetch(double&), which
    previously had no bounds check at all. Reported by doopal.
  • Fixed an unbounded allocation from an attacker-controlled SubjectArea
    component count: a single crafted 12-byte IFD entry could drive a
    multi-gigabyte std::vector::resize() from a file a few dozen bytes
    long. Found by this project's own new fuzzer.
  • Fixed a heap buffer overflow in EntryParser::Fetch methods reachable via
    a crafted SubjectArea length. (#25, fixes #24)
  • Fixed an integer overflow in the parseString bounds check that could
    pass validation on an attacker-controlled offset near UINT32_MAX. (#26,
    fixes #16)