1
0
mirror of https://github.com/cdcseacave/TinyEXIF.git synced 2026-07-21 19:23:01 +04:00

Robust parsing if missing offset

This commit is contained in:
cDc
2025-11-17 18:47:27 +02:00
parent 7a3167cc73
commit 27a750ecf5
3 changed files with 12 additions and 9 deletions
+1
View File
@@ -38,3 +38,4 @@ CMakeSettings.json
.vscode/ .vscode/
bin/ bin/
binaries/ binaries/
make/
+9 -7
View File
@@ -945,15 +945,17 @@ int EXIFInfo::parseFromEXIFSegment(const uint8_t* buf, unsigned len) {
// entries in the section. The last 4 bytes of the IFD contain an offset // entries in the section. The last 4 bytes of the IFD contain an offset
// to the next IFD, which means this IFD must contain exactly 6 + 12 * num // to the next IFD, which means this IFD must contain exactly 6 + 12 * num
// bytes of data. // bytes of data.
// Note that it's possible that the next IFD offset doesn't exist,
// so here the last 4 bytes are considered optional.
if (offs + 2 > len) if (offs + 2 > len)
return PARSE_CORRUPT_DATA; return PARSE_CORRUPT_DATA;
int num_entries = EntryParser::parse16(buf + offs, alignIntel); unsigned num_entries = EntryParser::parse16(buf + offs, alignIntel);
if (offs + 6 + 12 * num_entries > len) if (offs + 2 + 12 * num_entries > len)
return PARSE_CORRUPT_DATA; return PARSE_CORRUPT_DATA;
unsigned exif_sub_ifd_offset = len; unsigned exif_sub_ifd_offset = len;
unsigned gps_sub_ifd_offset = len; unsigned gps_sub_ifd_offset = len;
parser.Init(offs+2); parser.Init(offs+2);
while (--num_entries >= 0) { while (num_entries-- > 0) {
parser.ParseTag(); parser.ParseTag();
parseIFDImage(parser, exif_sub_ifd_offset, gps_sub_ifd_offset); parseIFDImage(parser, exif_sub_ifd_offset, gps_sub_ifd_offset);
} }
@@ -965,10 +967,10 @@ int EXIFInfo::parseFromEXIFSegment(const uint8_t* buf, unsigned len) {
if (exif_sub_ifd_offset + 4 <= len) { if (exif_sub_ifd_offset + 4 <= len) {
offs = exif_sub_ifd_offset; offs = exif_sub_ifd_offset;
num_entries = EntryParser::parse16(buf + offs, alignIntel); num_entries = EntryParser::parse16(buf + offs, alignIntel);
if (offs + 6 + 12 * num_entries > len) if (offs + 2 + 12 * num_entries > len)
return PARSE_CORRUPT_DATA; return PARSE_CORRUPT_DATA;
parser.Init(offs+2); parser.Init(offs+2);
while (--num_entries >= 0) { while (num_entries-- > 0) {
parser.ParseTag(); parser.ParseTag();
parseIFDExif(parser); parseIFDExif(parser);
} }
@@ -979,10 +981,10 @@ int EXIFInfo::parseFromEXIFSegment(const uint8_t* buf, unsigned len) {
if (gps_sub_ifd_offset + 4 <= len) { if (gps_sub_ifd_offset + 4 <= len) {
offs = gps_sub_ifd_offset; offs = gps_sub_ifd_offset;
num_entries = EntryParser::parse16(buf + offs, alignIntel); num_entries = EntryParser::parse16(buf + offs, alignIntel);
if (offs + 6 + 12 * num_entries > len) if (offs + 2 + 12 * num_entries > len)
return PARSE_CORRUPT_DATA; return PARSE_CORRUPT_DATA;
parser.Init(offs+2); parser.Init(offs+2);
while (--num_entries >= 0) { while (num_entries-- > 0) {
parser.ParseTag(); parser.ParseTag();
parseIFDGPS(parser); parseIFDGPS(parser);
} }
+2 -2
View File
@@ -294,13 +294,13 @@ public:
bool hasSpeed() const; // Return true if (speedX,speedY,speedZ) is available bool hasSpeed() const; // Return true if (speedX,speedY,speedZ) is available
bool hasAccuracy() const; // Return true if (accuracyXY,accuracyZ) is available bool hasAccuracy() const; // Return true if (accuracyXY,accuracyZ) is available
} GeoLocation; } GeoLocation;
struct TINYEXIF_LIB GPano_t { // Spherical metadata. https://developers.google.com/streetview/spherical-metadata struct TINYEXIF_LIB GPano_t { // Spherical metadata. https://developers.google.com/streetview/spherical-metadata
double PosePitchDegrees; // Pitch, measured in degrees above the horizon, for the center in the image. Value must be >= -90 and <= 90. double PosePitchDegrees; // Pitch, measured in degrees above the horizon, for the center in the image. Value must be >= -90 and <= 90.
double PoseRollDegrees; // Roll, measured in degrees, of the image where level with the horizon is 0. As roll increases, the horizon rotates counterclockwise in the image. Value must be > -180 and <= 180. double PoseRollDegrees; // Roll, measured in degrees, of the image where level with the horizon is 0. As roll increases, the horizon rotates counterclockwise in the image. Value must be > -180 and <= 180.
bool hasPosePitchDegrees() const; // Return true if PosePitchDegrees is available bool hasPosePitchDegrees() const; // Return true if PosePitchDegrees is available
bool hasPoseRollDegrees() const; // Return true if PoseRollDegrees is available bool hasPoseRollDegrees() const; // Return true if PoseRollDegrees is available
} GPano; } GPano;
struct TINYEXIF_LIB MicroVideo_t { // Google camera video file in metadata struct TINYEXIF_LIB MicroVideo_t { // Google camera video file in metadata
uint32_t HasMicroVideo; // not zero if exists uint32_t HasMicroVideo; // not zero if exists
uint32_t MicroVideoVersion; // just regularinfo uint32_t MicroVideoVersion; // just regularinfo
uint32_t MicroVideoOffset; // offset from end of file uint32_t MicroVideoOffset; // offset from end of file