Throw an exception on integer overflow.
This commit is contained in:
parent
395389aa15
commit
bb9ff53ebe
124
src/convert.cpp
124
src/convert.cpp
@ -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…
Reference in New Issue
Block a user