Throw an exception on integer overflow.

main
Kevin Backhouse 4 years ago
parent 395389aa15
commit bb9ff53ebe
No known key found for this signature in database
GPG Key ID: 9DD01852EE40366E

@ -859,6 +859,68 @@ namespace Exiv2 {
XMP_DateTime datetime; XMP_DateTime datetime;
try { try {
SXMPUtils::ConvertToDate(value, &datetime); SXMPUtils::ConvertToDate(value, &datetime);
char buf[30];
if (std::string(to) != "Exif.GPSInfo.GPSTimeStamp") {
SXMPUtils::ConvertToLocalTime(&datetime);
snprintf(buf, sizeof(buf), "%4d:%02d:%02d %02d:%02d:%02d",
static_cast<int>(datetime.year),
static_cast<int>(datetime.month),
static_cast<int>(datetime.day),
static_cast<int>(datetime.hour),
static_cast<int>(datetime.minute),
static_cast<int>(datetime.second));
buf[sizeof(buf) - 1] = 0;
(*exifData_)[to] = buf;
if (datetime.nanoSecond) {
const char* subsecTag = nullptr;
if (std::string(to) == "Exif.Image.DateTime") {
subsecTag = "Exif.Photo.SubSecTime";
}
else if (std::string(to) == "Exif.Photo.DateTimeOriginal") {
subsecTag = "Exif.Photo.SubSecTimeOriginal";
}
else if (std::string(to) == "Exif.Photo.DateTimeDigitized") {
subsecTag = "Exif.Photo.SubSecTimeDigitized";
}
if (subsecTag) {
prepareExifTarget(subsecTag, true);
(*exifData_)[subsecTag] = toString(datetime.nanoSecond);
}
}
}
else { // "Exif.GPSInfo.GPSTimeStamp"
// Ignore the time zone, assuming the time is in UTC as it should be
URational rhour(datetime.hour, 1);
URational rmin(datetime.minute, 1);
URational rsec(datetime.second, 1);
if (datetime.nanoSecond != 0) {
if (datetime.second != 0) {
// Add the seconds to rmin so that the ns fit into rsec
rmin.second = 60;
rmin.first *= 60;
rmin.first += datetime.second;
}
rsec.second = 1000000000;
rsec.first = datetime.nanoSecond;
}
std::ostringstream array;
array << rhour << " " << rmin << " " << rsec;
(*exifData_)[to] = array.str();
prepareExifTarget("Exif.GPSInfo.GPSDateStamp", true);
snprintf(buf, sizeof(buf), "%4d:%02d:%02d",
static_cast<int>(datetime.year),
static_cast<int>(datetime.month),
static_cast<int>(datetime.day));
buf[sizeof(buf) - 1] = 0;
(*exifData_)["Exif.GPSInfo.GPSDateStamp"] = buf;
}
} }
#ifndef SUPPRESS_WARNINGS #ifndef SUPPRESS_WARNINGS
catch (const XMP_Error& e) { catch (const XMP_Error& e) {
@ -870,68 +932,6 @@ namespace Exiv2 {
return; return;
} }
#endif // SUPPRESS_WARNINGS #endif // SUPPRESS_WARNINGS
char buf[30];
if (std::string(to) != "Exif.GPSInfo.GPSTimeStamp") {
SXMPUtils::ConvertToLocalTime(&datetime);
snprintf(buf, sizeof(buf), "%4d:%02d:%02d %02d:%02d:%02d",
static_cast<int>(datetime.year),
static_cast<int>(datetime.month),
static_cast<int>(datetime.day),
static_cast<int>(datetime.hour),
static_cast<int>(datetime.minute),
static_cast<int>(datetime.second));
buf[sizeof(buf) - 1] = 0;
(*exifData_)[to] = buf;
if (datetime.nanoSecond) {
const char* subsecTag = nullptr;
if (std::string(to) == "Exif.Image.DateTime") {
subsecTag = "Exif.Photo.SubSecTime";
}
else if (std::string(to) == "Exif.Photo.DateTimeOriginal") {
subsecTag = "Exif.Photo.SubSecTimeOriginal";
}
else if (std::string(to) == "Exif.Photo.DateTimeDigitized") {
subsecTag = "Exif.Photo.SubSecTimeDigitized";
}
if (subsecTag) {
prepareExifTarget(subsecTag, true);
(*exifData_)[subsecTag] = toString(datetime.nanoSecond);
}
}
}
else { // "Exif.GPSInfo.GPSTimeStamp"
// Ignore the time zone, assuming the time is in UTC as it should be
URational rhour(datetime.hour, 1);
URational rmin(datetime.minute, 1);
URational rsec(datetime.second, 1);
if (datetime.nanoSecond != 0) {
if (datetime.second != 0) {
// Add the seconds to rmin so that the ns fit into rsec
rmin.second = 60;
rmin.first *= 60;
rmin.first += datetime.second;
}
rsec.second = 1000000000;
rsec.first = datetime.nanoSecond;
}
std::ostringstream array;
array << rhour << " " << rmin << " " << rsec;
(*exifData_)[to] = array.str();
prepareExifTarget("Exif.GPSInfo.GPSDateStamp", true);
snprintf(buf, sizeof(buf), "%4d:%02d:%02d",
static_cast<int>(datetime.year),
static_cast<int>(datetime.month),
static_cast<int>(datetime.day));
buf[sizeof(buf) - 1] = 0;
(*exifData_)["Exif.GPSInfo.GPSDateStamp"] = buf;
}
if (erase_) xmpData_->erase(pos); if (erase_) xmpData_->erase(pos);
#else #else

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from system_tests import CaseMeta, path from system_tests import CaseMeta, path, check_no_ASAN_UBSAN_errors
class XMPUtilsSetTimeZoneIntegerOverflow(metaclass=CaseMeta): class XMPUtilsSetTimeZoneIntegerOverflow(metaclass=CaseMeta):
""" """
@ -17,109 +17,13 @@ class XMPUtilsSetTimeZoneIntegerOverflow(metaclass=CaseMeta):
"$exiv2 -q $filename2", "$exiv2 -q $filename2",
"$exiv2 -q $filename3", "$exiv2 -q $filename3",
"$exiv2 -q $filename4"] "$exiv2 -q $filename4"]
stderr = ["", "", "", ""] stderr = ["""$filename1: No Exif data found in the file
stdout = ["""File name : $filename1
File size : 170 Bytes
MIME type : application/rdf+xml
Image size : 0 x 0
Thumbnail : None
Camera make :
Camera model :
Image timestamp :
File number :
Exposure time :
Aperture :
Exposure bias :
Flash :
Flash bias :
Focal length :
Subject distance:
ISO speed :
Exposure mode :
Metering mode :
Macro mode :
Image quality :
White balance :
Copyright :
Exif comment :
""", """,
"""File name : $filename2 """$filename2: No Exif data found in the file
File size : 170 Bytes
MIME type : application/rdf+xml
Image size : 0 x 0
Thumbnail : None
Camera make :
Camera model :
Image timestamp :
File number :
Exposure time :
Aperture :
Exposure bias :
Flash :
Flash bias :
Focal length :
Subject distance:
ISO speed :
Exposure mode :
Metering mode :
Macro mode :
Image quality :
White balance :
Copyright :
Exif comment :
""", """,
"""File name : $filename3 """$filename3: No Exif data found in the file
File size : 160 Bytes
MIME type : application/rdf+xml
Image size : 0 x 0
Thumbnail : None
Camera make :
Camera model :
Image timestamp :
File number :
Exposure time :
Aperture :
Exposure bias :
Flash :
Flash bias :
Focal length :
Subject distance:
ISO speed :
Exposure mode :
Metering mode :
Macro mode :
Image quality :
White balance :
Copyright :
Exif comment :
""", """,
"""File name : $filename4 ""]
File size : 154 Bytes retval = [253, 253, 253, 0]
MIME type : application/rdf+xml
Image size : 0 x 0
Thumbnail : None
Camera make :
Camera model :
Image timestamp :
File number :
Exposure time :
Aperture :
Exposure bias :
Flash :
Flash bias :
Focal length :
Subject distance:
ISO speed :
Exposure mode :
Metering mode :
Macro mode :
Image quality :
White balance :
Copyright :
Exif comment :
"""] compare_stdout = check_no_ASAN_UBSAN_errors
retval = [0, 0, 0, 0]

@ -1960,11 +1960,10 @@ XMPUtils::SetTimeZone ( XMP_DateTime * xmpTime )
if ( now == -1 ) XMP_Throw ( "Failure from ANSI C time function", kXMPErr_ExternalFailure ); if ( now == -1 ) XMP_Throw ( "Failure from ANSI C time function", kXMPErr_ExternalFailure );
ansi_localtime ( &now, &tmLocal ); ansi_localtime ( &now, &tmLocal );
} else { } else {
// Fix for https://github.com/Exiv2/exiv2/issues/1901
if (xmpTime->year < std::numeric_limits<decltype(tmLocal.tm_year)>::min() + 1900) { if (xmpTime->year < std::numeric_limits<decltype(tmLocal.tm_year)>::min() + 1900) {
tmLocal.tm_year = std::numeric_limits<decltype(tmLocal.tm_year)>::min(); XMP_Throw ( "Invalid year", kXMPErr_BadParam);
} else if (xmpTime->year > std::numeric_limits<decltype(tmLocal.tm_year)>::max()) { } else if (xmpTime->year > std::numeric_limits<decltype(tmLocal.tm_year)>::max()) {
tmLocal.tm_year = std::numeric_limits<decltype(tmLocal.tm_year)>::max(); XMP_Throw ( "Invalid year", kXMPErr_BadParam);
} else { } else {
tmLocal.tm_year = xmpTime->year - 1900; tmLocal.tm_year = xmpTime->year - 1900;
} }

Loading…
Cancel
Save