namespace enforce.hpp functions to Internal
Signed-off-by: Rosen Penev <rosenp@gmail.com>
This commit is contained in:
parent
77834807c2
commit
376638259d
@ -1413,30 +1413,32 @@ int Adjust::adjustDateTime(Exiv2::ExifData& exifData, const std::string& key, co
|
||||
}
|
||||
|
||||
// bounds checking for yearAdjustment_
|
||||
enforce<std::overflow_error>(yearAdjustment_ >= std::numeric_limits<decltype(tm.tm_year)>::min(),
|
||||
"year adjustment too low");
|
||||
enforce<std::overflow_error>(yearAdjustment_ <= std::numeric_limits<decltype(tm.tm_year)>::max(),
|
||||
"year adjustment too high");
|
||||
Exiv2::Internal::enforce<std::overflow_error>(yearAdjustment_ >= std::numeric_limits<decltype(tm.tm_year)>::min(),
|
||||
"year adjustment too low");
|
||||
Exiv2::Internal::enforce<std::overflow_error>(yearAdjustment_ <= std::numeric_limits<decltype(tm.tm_year)>::max(),
|
||||
"year adjustment too high");
|
||||
const auto yearAdjustment = static_cast<decltype(tm.tm_year)>(yearAdjustment_);
|
||||
|
||||
// bounds checking for monthAdjustment_
|
||||
enforce<std::overflow_error>(monthAdjustment_ >= std::numeric_limits<decltype(tm.tm_mon)>::min(),
|
||||
"month adjustment too low");
|
||||
enforce<std::overflow_error>(monthAdjustment_ <= std::numeric_limits<decltype(tm.tm_mon)>::max(),
|
||||
"month adjustment too high");
|
||||
Exiv2::Internal::enforce<std::overflow_error>(monthAdjustment_ >= std::numeric_limits<decltype(tm.tm_mon)>::min(),
|
||||
"month adjustment too low");
|
||||
Exiv2::Internal::enforce<std::overflow_error>(monthAdjustment_ <= std::numeric_limits<decltype(tm.tm_mon)>::max(),
|
||||
"month adjustment too high");
|
||||
const auto monthAdjustment = static_cast<decltype(tm.tm_mon)>(monthAdjustment_);
|
||||
|
||||
// bounds checking for dayAdjustment_
|
||||
static constexpr time_t secondsInDay = 24 * 60 * 60;
|
||||
enforce<std::overflow_error>(dayAdjustment_ >= std::numeric_limits<time_t>::min() / secondsInDay,
|
||||
"day adjustment too low");
|
||||
enforce<std::overflow_error>(dayAdjustment_ <= std::numeric_limits<time_t>::max() / secondsInDay,
|
||||
"day adjustment too high");
|
||||
Exiv2::Internal::enforce<std::overflow_error>(dayAdjustment_ >= std::numeric_limits<time_t>::min() / secondsInDay,
|
||||
"day adjustment too low");
|
||||
Exiv2::Internal::enforce<std::overflow_error>(dayAdjustment_ <= std::numeric_limits<time_t>::max() / secondsInDay,
|
||||
"day adjustment too high");
|
||||
const auto dayAdjustment = static_cast<time_t>(dayAdjustment_);
|
||||
|
||||
// bounds checking for adjustment_
|
||||
enforce<std::overflow_error>(adjustment_ >= std::numeric_limits<time_t>::min(), "seconds adjustment too low");
|
||||
enforce<std::overflow_error>(adjustment_ <= std::numeric_limits<time_t>::max(), "seconds adjustment too high");
|
||||
Exiv2::Internal::enforce<std::overflow_error>(adjustment_ >= std::numeric_limits<time_t>::min(),
|
||||
"seconds adjustment too low");
|
||||
Exiv2::Internal::enforce<std::overflow_error>(adjustment_ <= std::numeric_limits<time_t>::max(),
|
||||
"seconds adjustment too high");
|
||||
const auto adjustment = static_cast<time_t>(adjustment_);
|
||||
|
||||
const auto monOverflow = Safe::add(tm.tm_mon, monthAdjustment) / 12;
|
||||
|
||||
@ -46,23 +46,23 @@ void mini1(const char* path) {
|
||||
|
||||
// Write nothing to a new structure, without a previous binary image
|
||||
wm = ExifParser::encode(blob, nullptr, 0, bigEndian, exifData);
|
||||
enforce(wm == wmIntrusive, Exiv2::ErrorCode::kerErrorMessage, "encode returned an unexpected value");
|
||||
Internal::enforce(wm == wmIntrusive, Exiv2::ErrorCode::kerErrorMessage, "encode returned an unexpected value");
|
||||
std::cout << "Test 1: Writing empty Exif data without original binary data: ok.\n";
|
||||
|
||||
// Write nothing, this time with a previous binary image
|
||||
DataBuf buf = readFile(path);
|
||||
wm = ExifParser::encode(blob, buf.c_data(), buf.size(), bigEndian, exifData);
|
||||
enforce(wm == wmIntrusive, Exiv2::ErrorCode::kerErrorMessage, "encode returned an unexpected value");
|
||||
Internal::enforce(wm == wmIntrusive, Exiv2::ErrorCode::kerErrorMessage, "encode returned an unexpected value");
|
||||
std::cout << "Test 2: Writing empty Exif data with original binary data: ok.\n";
|
||||
|
||||
// Write something to a new structure, without a previous binary image
|
||||
exifData["Exif.Photo.DateTimeOriginal"] = "Yesterday at noon";
|
||||
wm = ExifParser::encode(blob, nullptr, 0, bigEndian, exifData);
|
||||
enforce(wm == wmIntrusive, Exiv2::ErrorCode::kerErrorMessage, "encode returned an unexpected value");
|
||||
Internal::enforce(wm == wmIntrusive, Exiv2::ErrorCode::kerErrorMessage, "encode returned an unexpected value");
|
||||
std::cout << "Test 3: Wrote non-empty Exif data without original binary data:\n";
|
||||
exifData.clear();
|
||||
ByteOrder bo = ExifParser::decode(exifData, blob.data(), blob.size());
|
||||
enforce(bo == bigEndian, Exiv2::ErrorCode::kerErrorMessage, "decode returned an unexpected value");
|
||||
Internal::enforce(bo == bigEndian, Exiv2::ErrorCode::kerErrorMessage, "decode returned an unexpected value");
|
||||
print(exifData);
|
||||
}
|
||||
|
||||
|
||||
@ -66,13 +66,13 @@ void ReplaceStringInPlace(std::string& subject, std::string_view search, std::st
|
||||
namespace Exiv2 {
|
||||
void BasicIo::readOrThrow(byte* buf, size_t rcount, ErrorCode err) {
|
||||
const size_t nread = read(buf, rcount);
|
||||
enforce(nread == rcount, err);
|
||||
enforce(!error(), err);
|
||||
Internal::enforce(nread == rcount, err);
|
||||
Internal::enforce(!error(), err);
|
||||
}
|
||||
|
||||
void BasicIo::seekOrThrow(int64_t offset, Position pos, ErrorCode err) {
|
||||
const int r = seek(offset, pos);
|
||||
enforce(r == 0, err);
|
||||
Internal::enforce(r == 0, err);
|
||||
}
|
||||
|
||||
//! Internal Pimpl structure of class FileIo.
|
||||
@ -470,7 +470,7 @@ int FileIo::seek(int64_t offset, Position pos) {
|
||||
|
||||
size_t FileIo::tell() const {
|
||||
const long pos = std::ftell(p_->fp_);
|
||||
enforce(pos >= 0, ErrorCode::kerInputDataReadFailed);
|
||||
Internal::enforce(pos >= 0, ErrorCode::kerInputDataReadFailed);
|
||||
return static_cast<size_t>(pos);
|
||||
}
|
||||
|
||||
|
||||
@ -249,7 +249,7 @@ uint64_t BmffImage::boxHandler(std::ostream& out /* = std::cout*/, Exiv2::PrintS
|
||||
byte hdrbuf[2 * sizeof(uint32_t)];
|
||||
|
||||
size_t hdrsize = sizeof(hdrbuf);
|
||||
enforce(hdrsize <= static_cast<size_t>(pbox_end - address), Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(hdrsize <= static_cast<size_t>(pbox_end - address), Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
if (io_->read(reinterpret_cast<byte*>(&hdrbuf), sizeof(hdrbuf)) != sizeof(hdrbuf))
|
||||
return pbox_end;
|
||||
|
||||
@ -268,7 +268,7 @@ uint64_t BmffImage::boxHandler(std::ostream& out /* = std::cout*/, Exiv2::PrintS
|
||||
if (box_length == 1) {
|
||||
// The box size is encoded as a uint64_t, so we need to read another 8 bytes.
|
||||
hdrsize += 8;
|
||||
enforce(hdrsize <= static_cast<size_t>(pbox_end - address), Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(hdrsize <= static_cast<size_t>(pbox_end - address), Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
DataBuf data(8);
|
||||
io_->read(data.data(), data.size());
|
||||
box_length = data.read_uint64(0, endian_);
|
||||
@ -276,8 +276,8 @@ uint64_t BmffImage::boxHandler(std::ostream& out /* = std::cout*/, Exiv2::PrintS
|
||||
|
||||
// read data in box and restore file position
|
||||
const size_t restore = io_->tell();
|
||||
enforce(box_length >= hdrsize, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
enforce(box_length - hdrsize <= pbox_end - restore, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(box_length >= hdrsize, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(box_length - hdrsize <= pbox_end - restore, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
|
||||
const auto buffer_size = box_length - hdrsize;
|
||||
if (skipBox(box_type)) {
|
||||
@ -299,7 +299,7 @@ uint64_t BmffImage::boxHandler(std::ostream& out /* = std::cout*/, Exiv2::PrintS
|
||||
uint32_t flags = 0;
|
||||
|
||||
if (fullBox(box_type)) {
|
||||
enforce(data.size() - skip >= 4, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(data.size() - skip >= 4, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
flags = data.read_uint32(skip, endian_); // version/flags
|
||||
version = static_cast<uint8_t>(flags >> 24);
|
||||
flags &= 0x00ffffff;
|
||||
@ -309,7 +309,7 @@ uint64_t BmffImage::boxHandler(std::ostream& out /* = std::cout*/, Exiv2::PrintS
|
||||
switch (box_type) {
|
||||
// See notes in skipBox()
|
||||
case TAG_ftyp: {
|
||||
enforce(data.size() >= 4, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(data.size() >= 4, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
fileType_ = data.read_uint32(0, endian_);
|
||||
if (bTrace) {
|
||||
out << "brand: " << toAscii(fileType_);
|
||||
@ -323,7 +323,7 @@ uint64_t BmffImage::boxHandler(std::ostream& out /* = std::cout*/, Exiv2::PrintS
|
||||
bLF = false;
|
||||
}
|
||||
|
||||
enforce(data.size() - skip >= 2, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(data.size() - skip >= 2, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
uint16_t n = data.read_uint16(skip, endian_);
|
||||
skip += 2;
|
||||
|
||||
@ -335,7 +335,7 @@ uint64_t BmffImage::boxHandler(std::ostream& out /* = std::cout*/, Exiv2::PrintS
|
||||
|
||||
// 8.11.6.2
|
||||
case TAG_infe: { // .__._.__hvc1_ 2 0 0 1 0 1 0 0 104 118 99 49 0
|
||||
enforce(data.size() - skip >= 8, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(data.size() - skip >= 8, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
/* getULong (data.pData_+skip,endian_) ; */ skip += 4;
|
||||
uint16_t ID = data.read_uint16(skip, endian_);
|
||||
skip += 2;
|
||||
@ -344,7 +344,7 @@ uint64_t BmffImage::boxHandler(std::ostream& out /* = std::cout*/, Exiv2::PrintS
|
||||
// Check that the string has a '\0' terminator.
|
||||
const char* str = data.c_str(skip);
|
||||
const size_t maxlen = data.size() - skip;
|
||||
enforce(maxlen > 0 && strnlen(str, maxlen) < maxlen, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(maxlen > 0 && strnlen(str, maxlen) < maxlen, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
std::string name(str);
|
||||
if (name.find("Exif") != std::string::npos) { // "Exif" or "ExifExif"
|
||||
exifID_ = ID;
|
||||
@ -393,7 +393,7 @@ uint64_t BmffImage::boxHandler(std::ostream& out /* = std::cout*/, Exiv2::PrintS
|
||||
|
||||
// 8.11.3.1
|
||||
case TAG_iloc: {
|
||||
enforce(data.size() - skip >= 2, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(data.size() - skip >= 2, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
uint8_t u = data.read_uint8(skip++);
|
||||
uint16_t offsetSize = u >> 4;
|
||||
uint16_t lengthSize = u & 0xF;
|
||||
@ -406,7 +406,7 @@ uint64_t BmffImage::boxHandler(std::ostream& out /* = std::cout*/, Exiv2::PrintS
|
||||
#else
|
||||
skip++;
|
||||
#endif
|
||||
enforce(data.size() - skip >= (version < 2u ? 2u : 4u), Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(data.size() - skip >= (version < 2u ? 2u : 4u), Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
uint32_t itemCount = version < 2 ? data.read_uint16(skip, endian_) : data.read_uint32(skip, endian_);
|
||||
skip += version < 2 ? 2 : 4;
|
||||
if (itemCount && itemCount < box_length / 14 && offsetSize == 4 && lengthSize == 4 &&
|
||||
@ -419,8 +419,8 @@ uint64_t BmffImage::boxHandler(std::ostream& out /* = std::cout*/, Exiv2::PrintS
|
||||
size_t base = skip;
|
||||
for (uint32_t i = 0; i < itemCount; i++) {
|
||||
skip = base + i * step; // move in 14, 16 or 18 byte steps
|
||||
enforce(data.size() - skip >= (version > 2u ? 4u : 2u), Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
enforce(data.size() - skip >= step, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(data.size() - skip >= (version > 2u ? 4u : 2u), Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(data.size() - skip >= step, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
uint32_t ID = version > 2 ? data.read_uint32(skip, endian_) : data.read_uint16(skip, endian_);
|
||||
auto offset = [this, &data, skip, step] {
|
||||
if (step == 14 || step == 16)
|
||||
@ -445,7 +445,7 @@ uint64_t BmffImage::boxHandler(std::ostream& out /* = std::cout*/, Exiv2::PrintS
|
||||
} break;
|
||||
|
||||
case TAG_ispe: {
|
||||
enforce(data.size() - skip >= 12, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(data.size() - skip >= 12, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
skip += 4;
|
||||
uint32_t width = data.read_uint32(skip, endian_);
|
||||
skip += 4;
|
||||
@ -524,7 +524,7 @@ uint64_t BmffImage::boxHandler(std::ostream& out /* = std::cout*/, Exiv2::PrintS
|
||||
parseXmp(buffer_size, io_->tell());
|
||||
break;
|
||||
case TAG_brob: {
|
||||
enforce(data.size() >= 4, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(data.size() >= 4, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
uint32_t realType = data.read_uint32(0, endian_);
|
||||
if (bTrace) {
|
||||
out << "type: " << toAscii(realType);
|
||||
@ -534,7 +534,7 @@ uint64_t BmffImage::boxHandler(std::ostream& out /* = std::cout*/, Exiv2::PrintS
|
||||
brotliUncompress(data.c_data(4), data.size() - 4, arr);
|
||||
if (realType == TAG_exif) {
|
||||
uint32_t offset = Safe::add(arr.read_uint32(0, endian_), 4u);
|
||||
enforce(Safe::add(offset, 4u) < arr.size(), Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(Safe::add(offset, 4u) < arr.size(), Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
Internal::TiffParserWorker::decode(exifData(), iptcData(), xmpData(), arr.c_data(offset), arr.size() - offset,
|
||||
Internal::Tag::root, Internal::TiffMapping::findDecoder);
|
||||
} else if (realType == TAG_xml) {
|
||||
@ -580,10 +580,11 @@ uint64_t BmffImage::boxHandler(std::ostream& out /* = std::cout*/, Exiv2::PrintS
|
||||
}
|
||||
|
||||
void BmffImage::parseTiff(uint32_t root_tag, uint64_t length, uint64_t start) {
|
||||
enforce(start <= io_->size(), ErrorCode::kerCorruptedMetadata);
|
||||
enforce(length <= io_->size() - start, ErrorCode::kerCorruptedMetadata);
|
||||
enforce(start <= static_cast<uint64_t>(std::numeric_limits<int64_t>::max()), ErrorCode::kerCorruptedMetadata);
|
||||
enforce(length <= std::numeric_limits<size_t>::max(), ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(start <= io_->size(), ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(length <= io_->size() - start, ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(start <= static_cast<uint64_t>(std::numeric_limits<int64_t>::max()),
|
||||
ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(length <= std::numeric_limits<size_t>::max(), ErrorCode::kerCorruptedMetadata);
|
||||
|
||||
// read and parse exif data
|
||||
const size_t restore = io_->tell();
|
||||
@ -608,8 +609,8 @@ void BmffImage::parseTiff(uint32_t root_tag, uint64_t length, uint64_t start) {
|
||||
|
||||
void BmffImage::parseTiff(uint32_t root_tag, uint64_t length) {
|
||||
if (length > 8) {
|
||||
enforce(length - 8 <= io_->size() - io_->tell(), ErrorCode::kerCorruptedMetadata);
|
||||
enforce(length - 8 <= std::numeric_limits<size_t>::max(), ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(length - 8 <= io_->size() - io_->tell(), ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(length - 8 <= std::numeric_limits<size_t>::max(), ErrorCode::kerCorruptedMetadata);
|
||||
DataBuf data(static_cast<size_t>(length - 8u));
|
||||
const size_t bufRead = io_->read(data.data(), data.size());
|
||||
|
||||
@ -624,8 +625,8 @@ void BmffImage::parseTiff(uint32_t root_tag, uint64_t length) {
|
||||
}
|
||||
|
||||
void BmffImage::parseXmp(uint64_t length, uint64_t start) {
|
||||
enforce(start <= io_->size(), ErrorCode::kerCorruptedMetadata);
|
||||
enforce(length <= io_->size() - start, ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(start <= io_->size(), ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(length <= io_->size() - start, ErrorCode::kerCorruptedMetadata);
|
||||
|
||||
const size_t restore = io_->tell();
|
||||
io_->seek(static_cast<int64_t>(start), BasicIo::beg);
|
||||
@ -651,7 +652,7 @@ void BmffImage::parseCr3Preview(DataBuf& data, std::ostream& out, bool bTrace, u
|
||||
size_t height_offset, size_t size_offset, size_t relative_position) {
|
||||
// Derived from https://github.com/lclevy/canon_cr3
|
||||
const size_t here = io_->tell();
|
||||
enforce(here <= std::numeric_limits<size_t>::max() - relative_position, ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(here <= std::numeric_limits<size_t>::max() - relative_position, ErrorCode::kerCorruptedMetadata);
|
||||
NativePreview nativePreview;
|
||||
nativePreview.position_ = here + relative_position;
|
||||
nativePreview.width_ = data.read_uint16(width_offset, endian_);
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
|
||||
#include "error.hpp"
|
||||
|
||||
namespace Exiv2::Internal {
|
||||
/*!
|
||||
* @brief Ensure that condition is true, otherwise throw an exception of the
|
||||
* type exception_t
|
||||
@ -81,3 +82,4 @@ inline void enforce(bool condition, Exiv2::ErrorCode err_code, const T& arg1, co
|
||||
throw Exiv2::Error(err_code, arg1, arg2, arg3);
|
||||
}
|
||||
}
|
||||
} // namespace Exiv2::Internal
|
||||
|
||||
@ -238,7 +238,7 @@ std::string strError() {
|
||||
#else
|
||||
char buf[n] = {};
|
||||
const int ret = strerror_r(error, buf, n);
|
||||
enforce(ret != ERANGE, Exiv2::ErrorCode::kerCallFailed);
|
||||
Internal::enforce(ret != ERANGE, Exiv2::ErrorCode::kerCallFailed);
|
||||
#endif
|
||||
os << buf;
|
||||
// Issue# 908.
|
||||
|
||||
@ -308,7 +308,7 @@ void Image::printIFDStructure(BasicIo& io, std::ostream& out, Exiv2::PrintStruct
|
||||
io.readOrThrow(dir.data(), 2, ErrorCode::kerCorruptedMetadata);
|
||||
uint16_t dirLength = byteSwap2(dir, 0, bSwap);
|
||||
// Prevent infinite loops. (GHSA-m479-7frc-gqqg)
|
||||
enforce(dirLength > 0, ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(dirLength > 0, ErrorCode::kerCorruptedMetadata);
|
||||
|
||||
if (dirLength > 500) // tooBig
|
||||
throw Error(ErrorCode::kerTiffDirectoryTooLarge);
|
||||
@ -384,7 +384,7 @@ void Image::printIFDStructure(BasicIo& io, std::ostream& out, Exiv2::PrintStruct
|
||||
throw Error(ErrorCode::kerInvalidMalloc);
|
||||
}
|
||||
// Overflow check
|
||||
enforce(allocate64 <= std::numeric_limits<size_t>::max(), ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(allocate64 <= std::numeric_limits<size_t>::max(), ErrorCode::kerCorruptedMetadata);
|
||||
DataBuf buf(allocate64); // allocate a buffer
|
||||
std::copy_n(dir.c_data(8), 4, buf.begin()); // copy dir[8:11] into buffer (short strings)
|
||||
|
||||
|
||||
@ -290,12 +290,12 @@ void IptcData::printStructure(std::ostream& out, const Slice<byte*>& bytes, size
|
||||
char buff[100];
|
||||
uint16_t record = bytes.at(i + 1);
|
||||
uint16_t dataset = bytes.at(i + 2);
|
||||
enforce(bytes.size() - i >= 5, ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(bytes.size() - i >= 5, ErrorCode::kerCorruptedMetadata);
|
||||
uint16_t len = getUShort(bytes.subSlice(i + 3, bytes.size()), bigEndian);
|
||||
snprintf(buff, sizeof(buff), " %6d | %7d | %-24s | %6d | ", record, dataset,
|
||||
Exiv2::IptcDataSets::dataSetName(dataset, record).c_str(), len);
|
||||
|
||||
enforce(bytes.size() - i >= 5 + static_cast<size_t>(len), ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(bytes.size() - i >= 5 + static_cast<size_t>(len), ErrorCode::kerCorruptedMetadata);
|
||||
out << buff << Internal::binaryToString(makeSlice(bytes, i + 5, i + 5 + (len > 40 ? 40 : len)))
|
||||
<< (len > 40 ? "..." : "") << std::endl;
|
||||
i += 5 + len;
|
||||
|
||||
@ -157,7 +157,7 @@ void Jp2Image::readMetadata() {
|
||||
<< "Position: " << position << " box type: " << toAscii(box.type) << " length: " << box.length
|
||||
<< std::endl;
|
||||
#endif
|
||||
enforce(box.length <= boxHSize + io_->size() - io_->tell(), ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(box.length <= boxHSize + io_->size() - io_->tell(), ErrorCode::kerCorruptedMetadata);
|
||||
|
||||
if (box.length == 0)
|
||||
return;
|
||||
@ -245,7 +245,7 @@ void Jp2Image::readMetadata() {
|
||||
ihdr.imageHeight = getULong(reinterpret_cast<byte*>(&ihdr.imageHeight), bigEndian);
|
||||
ihdr.imageWidth = getULong(reinterpret_cast<byte*>(&ihdr.imageWidth), bigEndian);
|
||||
ihdr.componentCount = getShort(reinterpret_cast<byte*>(&ihdr.componentCount), bigEndian);
|
||||
enforce(ihdr.c == 7, ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(ihdr.c == 7, ErrorCode::kerCorruptedMetadata);
|
||||
|
||||
pixelWidth_ = ihdr.imageWidth;
|
||||
pixelHeight_ = ihdr.imageHeight;
|
||||
@ -276,7 +276,7 @@ void Jp2Image::readMetadata() {
|
||||
#ifdef EXIV2_DEBUG_MESSAGES
|
||||
std::cout << "Exiv2::Jp2Image::readMetadata: Exif data found" << std::endl;
|
||||
#endif
|
||||
enforce(box.length >= boxHSize + sizeof(uuid), ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(box.length >= boxHSize + sizeof(uuid), ErrorCode::kerCorruptedMetadata);
|
||||
rawData.alloc(box.length - (boxHSize + sizeof(uuid)));
|
||||
bufRead = io_->read(rawData.data(), rawData.size());
|
||||
if (io_->error())
|
||||
@ -324,7 +324,7 @@ void Jp2Image::readMetadata() {
|
||||
#ifdef EXIV2_DEBUG_MESSAGES
|
||||
std::cout << "Exiv2::Jp2Image::readMetadata: Iptc data found" << std::endl;
|
||||
#endif
|
||||
enforce(box.length >= boxHSize + sizeof(uuid), ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(box.length >= boxHSize + sizeof(uuid), ErrorCode::kerCorruptedMetadata);
|
||||
rawData.alloc(box.length - (boxHSize + sizeof(uuid)));
|
||||
bufRead = io_->read(rawData.data(), rawData.size());
|
||||
if (io_->error())
|
||||
@ -344,7 +344,7 @@ void Jp2Image::readMetadata() {
|
||||
#ifdef EXIV2_DEBUG_MESSAGES
|
||||
std::cout << "Exiv2::Jp2Image::readMetadata: Xmp data found" << std::endl;
|
||||
#endif
|
||||
enforce(box.length >= boxHSize + sizeof(uuid), ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(box.length >= boxHSize + sizeof(uuid), ErrorCode::kerCorruptedMetadata);
|
||||
rawData.alloc(box.length - (boxHSize + sizeof(uuid)));
|
||||
bufRead = io_->read(rawData.data(), rawData.size());
|
||||
if (io_->error())
|
||||
@ -420,7 +420,7 @@ void Jp2Image::printStructure(std::ostream& out, PrintStructureOption option, si
|
||||
const size_t position = io_->tell();
|
||||
box.length = getULong(reinterpret_cast<byte*>(&box.length), bigEndian);
|
||||
box.type = getULong(reinterpret_cast<byte*>(&box.type), bigEndian);
|
||||
enforce(box.length <= boxHSize + io_->size() - io_->tell(), ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(box.length <= boxHSize + io_->size() - io_->tell(), ErrorCode::kerCorruptedMetadata);
|
||||
|
||||
if (bPrint) {
|
||||
out << Internal::stringFormat("%8ld | %8ld | ", position - boxHSize, static_cast<size_t>(box.length))
|
||||
@ -473,7 +473,7 @@ void Jp2Image::printStructure(std::ostream& out, PrintStructureOption option, si
|
||||
}
|
||||
|
||||
if (subBox.type == kJp2BoxTypeImageHeader) {
|
||||
enforce(subBox.length == 22, ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(subBox.length == 22, ErrorCode::kerCorruptedMetadata);
|
||||
// height (4), width (4), componentsCount (2), bpc (1)
|
||||
auto compressionType = data.read_uint8(11);
|
||||
auto unkC = data.read_uint8(12);
|
||||
@ -485,7 +485,7 @@ void Jp2Image::printStructure(std::ostream& out, PrintStructureOption option, si
|
||||
const size_t pad = 3; // don't know why there are 3 padding bytes
|
||||
|
||||
// Bounds-check for the `getULong()` below, which reads 4 bytes, starting at `pad`.
|
||||
enforce(data.size() >= pad + 4, ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(data.size() >= pad + 4, ErrorCode::kerCorruptedMetadata);
|
||||
|
||||
/// \todo A conforming JP2 reader shall ignore all Colour Specification boxes after the first.
|
||||
auto METH = data.read_uint8(0);
|
||||
@ -502,7 +502,7 @@ void Jp2Image::printStructure(std::ostream& out, PrintStructureOption option, si
|
||||
if (bPrint) {
|
||||
out << " | iccLength:" << iccLength;
|
||||
}
|
||||
enforce(iccLength <= data.size() - pad, ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(iccLength <= data.size() - pad, ErrorCode::kerCorruptedMetadata);
|
||||
if (bICC) {
|
||||
out.write(data.c_str(pad), iccLength);
|
||||
}
|
||||
@ -532,7 +532,7 @@ void Jp2Image::printStructure(std::ostream& out, PrintStructureOption option, si
|
||||
}
|
||||
|
||||
DataBuf rawData;
|
||||
enforce(box.length >= sizeof(uuid) + boxHSize, ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(box.length >= sizeof(uuid) + boxHSize, ErrorCode::kerCorruptedMetadata);
|
||||
rawData.alloc(box.length - sizeof(uuid) - boxHSize);
|
||||
const size_t bufRead = io_->read(rawData.data(), rawData.size());
|
||||
if (io_->error())
|
||||
@ -602,14 +602,14 @@ void Jp2Image::encodeJp2Header(const DataBuf& boxBuf, DataBuf& outBuf) {
|
||||
DataBuf output(boxBuf.size() + iccProfile_.size() + 100); // allocate sufficient space
|
||||
size_t outlen = boxHSize; // now many bytes have we written to output?
|
||||
size_t inlen = boxHSize; // how many bytes have we read from boxBuf?
|
||||
enforce(boxHSize <= output.size(), ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(boxHSize <= output.size(), ErrorCode::kerCorruptedMetadata);
|
||||
uint32_t length = getULong(boxBuf.c_data(0), bigEndian);
|
||||
enforce(length <= output.size(), ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(length <= output.size(), ErrorCode::kerCorruptedMetadata);
|
||||
uint32_t count = boxHSize;
|
||||
bool bWroteColor = false;
|
||||
|
||||
while (count < length && !bWroteColor) {
|
||||
enforce(boxHSize <= length - count, ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(boxHSize <= length - count, ErrorCode::kerCorruptedMetadata);
|
||||
Internal::Jp2BoxHeader subBox;
|
||||
memcpy(&subBox, boxBuf.c_data(count), boxHSize);
|
||||
Internal::Jp2BoxHeader newBox = subBox;
|
||||
@ -621,8 +621,8 @@ void Jp2Image::encodeJp2Header(const DataBuf& boxBuf, DataBuf& outBuf) {
|
||||
std::cout << "Jp2Image::encodeJp2Header subbox: " << toAscii(subBox.type) << " length = " << subBox.length
|
||||
<< std::endl;
|
||||
#endif
|
||||
enforce(subBox.length > 0, ErrorCode::kerCorruptedMetadata);
|
||||
enforce(subBox.length <= length - count, ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(subBox.length > 0, ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(subBox.length <= length - count, ErrorCode::kerCorruptedMetadata);
|
||||
count += subBox.length;
|
||||
newBox.type = subBox.type;
|
||||
} else {
|
||||
@ -637,7 +637,7 @@ void Jp2Image::encodeJp2Header(const DataBuf& boxBuf, DataBuf& outBuf) {
|
||||
if (!iccProfileDefined()) {
|
||||
const char* pad = "\x01\x00\x00\x00\x00\x00\x10\x00\x00\x05\x1cuuid";
|
||||
uint32_t psize = 15;
|
||||
enforce(newlen <= output.size() - outlen, ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(newlen <= output.size() - outlen, ErrorCode::kerCorruptedMetadata);
|
||||
ul2Data(reinterpret_cast<byte*>(&newBox.length), psize, bigEndian);
|
||||
ul2Data(reinterpret_cast<byte*>(&newBox.type), newBox.type, bigEndian);
|
||||
std::copy_n(reinterpret_cast<char*>(&newBox), sizeof(newBox), output.begin() + outlen);
|
||||
@ -646,7 +646,7 @@ void Jp2Image::encodeJp2Header(const DataBuf& boxBuf, DataBuf& outBuf) {
|
||||
const char* pad = "\x02\x00\x00";
|
||||
uint32_t psize = 3;
|
||||
newlen = sizeof(newBox) + psize + iccProfile_.size();
|
||||
enforce(newlen <= output.size() - outlen, ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(newlen <= output.size() - outlen, ErrorCode::kerCorruptedMetadata);
|
||||
ul2Data(reinterpret_cast<byte*>(&newBox.length), static_cast<uint32_t>(newlen), bigEndian);
|
||||
ul2Data(reinterpret_cast<byte*>(&newBox.type), newBox.type, bigEndian);
|
||||
std::copy_n(reinterpret_cast<char*>(&newBox), sizeof(newBox), output.begin() + outlen);
|
||||
@ -654,7 +654,7 @@ void Jp2Image::encodeJp2Header(const DataBuf& boxBuf, DataBuf& outBuf) {
|
||||
std::copy(iccProfile_.begin(), iccProfile_.end(), output.begin() + outlen + sizeof(newBox) + psize);
|
||||
}
|
||||
} else {
|
||||
enforce(newlen <= output.size() - outlen, ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(newlen <= output.size() - outlen, ErrorCode::kerCorruptedMetadata);
|
||||
std::copy_n(boxBuf.c_data(inlen), subBox.length, output.begin() + outlen);
|
||||
}
|
||||
|
||||
@ -734,7 +734,8 @@ void Jp2Image::doWriteMetadata(BasicIo& outIo) {
|
||||
}
|
||||
|
||||
// Prevent a malicious file from causing a large memory allocation.
|
||||
enforce(box.length - 8 <= static_cast<size_t>(io_->size() - io_->tell()), ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(box.length - 8 <= static_cast<size_t>(io_->size() - io_->tell()),
|
||||
ErrorCode::kerCorruptedMetadata);
|
||||
|
||||
// Read whole box : Box header + Box data (not fixed size - can be null).
|
||||
DataBuf boxBuf(box.length); // Box header (8 bytes) + box data.
|
||||
@ -831,7 +832,7 @@ void Jp2Image::doWriteMetadata(BasicIo& outIo) {
|
||||
}
|
||||
|
||||
case kJp2BoxTypeUuid: {
|
||||
enforce(boxBuf.size() >= 24, ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(boxBuf.size() >= 24, ErrorCode::kerCorruptedMetadata);
|
||||
if (boxBuf.cmpBytes(8, kJp2UuidExif, 16) == 0) {
|
||||
#ifdef EXIV2_DEBUG_MESSAGES
|
||||
std::cout << "Exiv2::Jp2Image::doWriteMetadata: strip Exif Uuid box" << std::endl;
|
||||
|
||||
@ -31,6 +31,7 @@
|
||||
|
||||
namespace Exiv2 {
|
||||
|
||||
using Exiv2::Internal::enforce;
|
||||
using Exiv2::Internal::startsWith;
|
||||
namespace {
|
||||
// JPEG Segment markers (The first byte is always 0xFF, the value of these constants correspond to the 2nd byte)
|
||||
@ -61,11 +62,11 @@ constexpr auto exifId_ = "Exif\0\0"; //!< Exif identifier
|
||||
constexpr auto xmpId_ = "http://ns.adobe.com/xap/1.0/\0"; //!< XMP packet identifier
|
||||
constexpr auto iccId_ = "ICC_PROFILE\0"; //!< ICC profile identifier
|
||||
|
||||
inline bool inRange(int lo, int value, int hi) {
|
||||
constexpr bool inRange(int lo, int value, int hi) {
|
||||
return lo <= value && value <= hi;
|
||||
}
|
||||
|
||||
inline bool inRange2(int value, int lo1, int hi1, int lo2, int hi2) {
|
||||
constexpr bool inRange2(int value, int lo1, int hi1, int lo2, int hi2) {
|
||||
return inRange(lo1, value, hi1) || inRange(lo2, value, hi2);
|
||||
}
|
||||
|
||||
|
||||
@ -1446,19 +1446,19 @@ static long getKeyLong(const std::string& key, const ExifData* metadata, int whi
|
||||
/*! http://stackoverflow.com/questions/1798112/removing-leading-and-trailing-spaces-from-a-string
|
||||
trim from left
|
||||
*/
|
||||
inline std::string& ltrim(std::string& s, const char* t = " \t\n\r\f\v") {
|
||||
static std::string& ltrim(std::string& s, const char* t = " \t\n\r\f\v") {
|
||||
s.erase(0, s.find_first_not_of(t));
|
||||
return s;
|
||||
}
|
||||
|
||||
//! trim from right
|
||||
inline std::string& rtrim(std::string& s, const char* t = " \t\n\r\f\v") {
|
||||
static std::string& rtrim(std::string& s, const char* t = " \t\n\r\f\v") {
|
||||
s.erase(s.find_last_not_of(t) + 1);
|
||||
return s;
|
||||
}
|
||||
|
||||
//! trim from left & right
|
||||
inline std::string& trim(std::string& s, const char* t = " \t\n\r\f\v") {
|
||||
static std::string& trim(std::string& s, const char* t = " \t\n\r\f\v") {
|
||||
return ltrim(rtrim(s, t), t);
|
||||
}
|
||||
|
||||
|
||||
@ -77,22 +77,22 @@ void MrwImage::readMetadata() {
|
||||
uint32_t const end = getULong(tmp + 4, bigEndian);
|
||||
|
||||
pos += len;
|
||||
enforce(pos <= end, ErrorCode::kerFailedToReadImageData);
|
||||
Internal::enforce(pos <= end, ErrorCode::kerFailedToReadImageData);
|
||||
io_->read(tmp, len);
|
||||
if (io_->error() || io_->eof())
|
||||
throw Error(ErrorCode::kerFailedToReadImageData);
|
||||
|
||||
while (memcmp(tmp + 1, "TTW", 3) != 0) {
|
||||
uint32_t const siz = getULong(tmp + 4, bigEndian);
|
||||
enforce(siz <= end - pos, ErrorCode::kerFailedToReadImageData);
|
||||
Internal::enforce(siz <= end - pos, ErrorCode::kerFailedToReadImageData);
|
||||
pos += siz;
|
||||
io_->seek(siz, BasicIo::cur);
|
||||
enforce(!io_->error() && !io_->eof(), ErrorCode::kerFailedToReadImageData);
|
||||
Internal::enforce(!io_->error() && !io_->eof(), ErrorCode::kerFailedToReadImageData);
|
||||
|
||||
enforce(len <= end - pos, ErrorCode::kerFailedToReadImageData);
|
||||
Internal::enforce(len <= end - pos, ErrorCode::kerFailedToReadImageData);
|
||||
pos += len;
|
||||
io_->read(tmp, len);
|
||||
enforce(!io_->error() && !io_->eof(), ErrorCode::kerFailedToReadImageData);
|
||||
Internal::enforce(!io_->error() && !io_->eof(), ErrorCode::kerFailedToReadImageData);
|
||||
}
|
||||
|
||||
const uint32_t siz = getULong(tmp + 4, bigEndian);
|
||||
@ -101,10 +101,10 @@ void MrwImage::readMetadata() {
|
||||
// greater than io_->size() then it is definitely invalid. But the
|
||||
// exact bounds checking is done by the call to io_->read, which
|
||||
// will fail if there are fewer than siz bytes left to read.
|
||||
enforce(siz <= io_->size(), ErrorCode::kerFailedToReadImageData);
|
||||
Internal::enforce(siz <= io_->size(), ErrorCode::kerFailedToReadImageData);
|
||||
DataBuf buf(siz);
|
||||
io_->read(buf.data(), buf.size());
|
||||
enforce(!io_->error() && !io_->eof(), ErrorCode::kerFailedToReadImageData);
|
||||
Internal::enforce(!io_->error() && !io_->eof(), ErrorCode::kerFailedToReadImageData);
|
||||
|
||||
ByteOrder bo = TiffParser::decode(exifData_, iptcData_, xmpData_, buf.c_data(), buf.size());
|
||||
setByteOrder(bo);
|
||||
|
||||
@ -87,7 +87,7 @@ void PgfImage::readMetadata() {
|
||||
|
||||
// And now, the most interesting, the user data byte array where metadata are stored as small image.
|
||||
|
||||
enforce(headerSize <= std::numeric_limits<size_t>::max() - 8, ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(headerSize <= std::numeric_limits<size_t>::max() - 8, ErrorCode::kerCorruptedMetadata);
|
||||
size_t size = headerSize + 8 - io_->tell();
|
||||
|
||||
#ifdef EXIV2_DEBUG_MESSAGES
|
||||
|
||||
@ -154,7 +154,7 @@ DataBuf Photoshop::setIptcIrb(const byte* pPsData, size_t sizePsData, const Iptc
|
||||
// Write existing stuff after record, skip the current and all remaining IPTC blocks
|
||||
size_t pos = sizeFront;
|
||||
auto nextSizeData = Safe::add<long>(static_cast<long>(sizePsData), -static_cast<long>(pos));
|
||||
enforce(nextSizeData >= 0, ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(nextSizeData >= 0, ErrorCode::kerCorruptedMetadata);
|
||||
while (0 == Photoshop::locateIptcIrb(pPsData + pos, nextSizeData, &record, sizeHdr, sizeIptc)) {
|
||||
const auto newPos = static_cast<size_t>(record - pPsData);
|
||||
if (newPos > pos) { // Copy data up to the IPTC IRB
|
||||
@ -162,7 +162,7 @@ DataBuf Photoshop::setIptcIrb(const byte* pPsData, size_t sizePsData, const Iptc
|
||||
}
|
||||
pos = newPos + sizeHdr + sizeIptc + (sizeIptc & 1); // Skip the IPTC IRB
|
||||
nextSizeData = Safe::add<long>(static_cast<long>(sizePsData), -static_cast<long>(pos));
|
||||
enforce(nextSizeData >= 0, ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(nextSizeData >= 0, ErrorCode::kerCorruptedMetadata);
|
||||
}
|
||||
if (pos < sizePsData) {
|
||||
append(psBlob, pPsData + pos, sizePsData - pos);
|
||||
|
||||
@ -41,7 +41,7 @@ constexpr unsigned char pngBlank[] = {
|
||||
const auto nullComp = reinterpret_cast<const Exiv2::byte*>("\0\0");
|
||||
const auto typeExif = reinterpret_cast<const Exiv2::byte*>("eXIf");
|
||||
const auto typeICCP = reinterpret_cast<const Exiv2::byte*>("iCCP");
|
||||
inline bool compare(std::string_view str, const Exiv2::DataBuf& buf) {
|
||||
bool compare(std::string_view str, const Exiv2::DataBuf& buf) {
|
||||
const auto minlen = std::min(str.size(), buf.size());
|
||||
return buf.cmpBytes(0, str.data(), minlen) == 0;
|
||||
}
|
||||
|
||||
@ -731,7 +731,7 @@ DataBuf LoaderTiff::getData() const {
|
||||
dataValue.setDataArea(base + offset, size);
|
||||
} else {
|
||||
// FIXME: the buffer is probably copied twice, it should be optimized
|
||||
enforce(size_ <= io.size(), ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(size_ <= io.size(), ErrorCode::kerCorruptedMetadata);
|
||||
DataBuf buf(size_);
|
||||
uint32_t idxBuf = 0;
|
||||
for (size_t i = 0; i < sizes.count(); i++) {
|
||||
@ -742,7 +742,7 @@ DataBuf LoaderTiff::getData() const {
|
||||
// see the constructor of LoaderTiff
|
||||
// But e.g in malicious files some of these values could be negative
|
||||
// That's why we check again for each step here to really make sure we don't overstep
|
||||
enforce(Safe::add(idxBuf, size) <= size_, ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(Safe::add(idxBuf, size) <= size_, ErrorCode::kerCorruptedMetadata);
|
||||
if (size != 0 && Safe::add(offset, size) <= static_cast<uint32_t>(io.size())) {
|
||||
std::copy_n(base + offset, size, buf.begin() + idxBuf);
|
||||
}
|
||||
|
||||
@ -167,10 +167,10 @@ void PsdImage::readMetadata() {
|
||||
throw Error(ErrorCode::kerNotAnImage, "Photoshop");
|
||||
}
|
||||
uint32_t resourcesLength = getULong(buf, bigEndian);
|
||||
enforce(resourcesLength < io_->size(), Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(resourcesLength < io_->size(), Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
|
||||
while (resourcesLength > 0) {
|
||||
enforce(resourcesLength >= 8, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(resourcesLength >= 8, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
resourcesLength -= 8;
|
||||
if (io_->read(buf, 8) != 8) {
|
||||
throw Error(ErrorCode::kerNotAnImage, "Photoshop");
|
||||
@ -183,12 +183,12 @@ void PsdImage::readMetadata() {
|
||||
uint32_t resourceNameLength = buf[6] & ~1;
|
||||
|
||||
// skip the resource name, plus any padding
|
||||
enforce(resourceNameLength <= resourcesLength, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(resourceNameLength <= resourcesLength, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
resourcesLength -= resourceNameLength;
|
||||
io_->seek(resourceNameLength, BasicIo::cur);
|
||||
|
||||
// read resource size
|
||||
enforce(resourcesLength >= 4, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(resourcesLength >= 4, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
resourcesLength -= 4;
|
||||
if (io_->read(buf, 4) != 4) {
|
||||
throw Error(ErrorCode::kerNotAnImage, "Photoshop");
|
||||
@ -201,10 +201,10 @@ void PsdImage::readMetadata() {
|
||||
<< "\n";
|
||||
#endif
|
||||
|
||||
enforce(resourceSize <= resourcesLength, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(resourceSize <= resourcesLength, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
readResourceBlock(resourceId, resourceSize);
|
||||
resourceSize = (resourceSize + 1) & ~1; // pad to even
|
||||
enforce(resourceSize <= resourcesLength, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(resourceSize <= resourcesLength, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
resourcesLength -= resourceSize;
|
||||
io_->seek(curOffset + resourceSize, BasicIo::beg);
|
||||
}
|
||||
|
||||
@ -243,17 +243,17 @@ void RafImage::readMetadata() {
|
||||
uint32_t jpg_img_off_u32 = Exiv2::getULong(jpg_img_offset, bigEndian);
|
||||
uint32_t jpg_img_len_u32 = Exiv2::getULong(jpg_img_length, bigEndian);
|
||||
|
||||
enforce(Safe::add(jpg_img_off_u32, jpg_img_len_u32) <= io_->size(), ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(Safe::add(jpg_img_off_u32, jpg_img_len_u32) <= io_->size(), ErrorCode::kerCorruptedMetadata);
|
||||
|
||||
#if LONG_MAX < UINT_MAX
|
||||
enforce(jpg_img_off_u32 <= std::numeric_limits<uint32_t>::max(), ErrorCode::kerCorruptedMetadata);
|
||||
enforce(jpg_img_len_u32 <= std::numeric_limits<uint32_t>::max(), ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(jpg_img_off_u32 <= std::numeric_limits<uint32_t>::max(), ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(jpg_img_len_u32 <= std::numeric_limits<uint32_t>::max(), ErrorCode::kerCorruptedMetadata);
|
||||
#endif
|
||||
|
||||
auto jpg_img_off = static_cast<long>(jpg_img_off_u32);
|
||||
auto jpg_img_len = static_cast<long>(jpg_img_len_u32);
|
||||
|
||||
enforce(jpg_img_len >= 12, ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(jpg_img_len >= 12, ErrorCode::kerCorruptedMetadata);
|
||||
|
||||
DataBuf buf(jpg_img_len - 12);
|
||||
if (io_->seek(jpg_img_off + 12, BasicIo::beg) != 0)
|
||||
@ -285,7 +285,7 @@ void RafImage::readMetadata() {
|
||||
uint32_t tiffLength = Exiv2::getULong(readBuff, bigEndian);
|
||||
|
||||
// sanity check. Does tiff lie inside the file?
|
||||
enforce(Safe::add(tiffOffset, tiffLength) <= io_->size(), ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(Safe::add(tiffOffset, tiffLength) <= io_->size(), ErrorCode::kerCorruptedMetadata);
|
||||
|
||||
if (io_->seek(tiffOffset, BasicIo::beg) != 0)
|
||||
throw Error(ErrorCode::kerFailedToReadImageData);
|
||||
|
||||
@ -192,9 +192,9 @@ const char* Exiv2::DataBuf::c_str(size_t offset) const {
|
||||
// free functions
|
||||
|
||||
static void checkDataBufBounds(const DataBuf& buf, size_t end) {
|
||||
enforce<std::invalid_argument>(end <= static_cast<size_t>(std::numeric_limits<long>::max()),
|
||||
"end of slice too large to be compared with DataBuf bounds.");
|
||||
enforce<std::out_of_range>(end <= buf.size(), "Invalid slice bounds specified");
|
||||
Internal::enforce<std::invalid_argument>(end <= static_cast<size_t>(std::numeric_limits<long>::max()),
|
||||
"end of slice too large to be compared with DataBuf bounds.");
|
||||
Internal::enforce<std::out_of_range>(end <= buf.size(), "Invalid slice bounds specified");
|
||||
}
|
||||
|
||||
Slice<byte*> makeSlice(DataBuf& buf, size_t begin, size_t end) {
|
||||
|
||||
@ -954,7 +954,7 @@ size_t TimeValue::copy(byte* buf, ByteOrder /*byteOrder*/) const {
|
||||
"%02d%02d%02d%1c%02d%02d", time_.hour, time_.minute, time_.second,
|
||||
plusMinus, abs(time_.tzHour), abs(time_.tzMinute)));
|
||||
|
||||
enforce(wrote == 11, Exiv2::ErrorCode::kerUnsupportedTimeFormat);
|
||||
Internal::enforce(wrote == 11, Exiv2::ErrorCode::kerUnsupportedTimeFormat);
|
||||
std::memcpy(buf, temp, wrote);
|
||||
return wrote;
|
||||
}
|
||||
|
||||
@ -173,7 +173,7 @@ void WebPImage::doWriteMetadata(BasicIo& outIo) {
|
||||
has_vp8x = true;
|
||||
}
|
||||
if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_VP8X) && !has_size) {
|
||||
enforce(size_u32 >= 10, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(size_u32 >= 10, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
has_size = true;
|
||||
byte size_buf[WEBP_TAG_SIZE];
|
||||
|
||||
@ -202,7 +202,7 @@ void WebPImage::doWriteMetadata(BasicIo& outIo) {
|
||||
}
|
||||
#endif
|
||||
if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_VP8) && !has_size) {
|
||||
enforce(size_u32 >= 10, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(size_u32 >= 10, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
has_size = true;
|
||||
byte size_buf[2];
|
||||
|
||||
@ -220,13 +220,13 @@ void WebPImage::doWriteMetadata(BasicIo& outIo) {
|
||||
|
||||
/* Chunk with lossless image data. */
|
||||
if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_VP8L) && !has_alpha) {
|
||||
enforce(size_u32 >= 5, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(size_u32 >= 5, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
if ((payload.read_uint8(4) & WEBP_VP8X_ALPHA_BIT) == WEBP_VP8X_ALPHA_BIT) {
|
||||
has_alpha = true;
|
||||
}
|
||||
}
|
||||
if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_VP8L) && !has_size) {
|
||||
enforce(size_u32 >= 5, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(size_u32 >= 5, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
has_size = true;
|
||||
byte size_buf_w[2];
|
||||
byte size_buf_h[3];
|
||||
@ -250,13 +250,13 @@ void WebPImage::doWriteMetadata(BasicIo& outIo) {
|
||||
|
||||
/* Chunk with animation frame. */
|
||||
if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_ANMF) && !has_alpha) {
|
||||
enforce(size_u32 >= 6, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(size_u32 >= 6, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
if ((payload.read_uint8(5) & 0x2) == 0x2) {
|
||||
has_alpha = true;
|
||||
}
|
||||
}
|
||||
if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_ANMF) && !has_size) {
|
||||
enforce(size_u32 >= 12, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(size_u32 >= 12, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
has_size = true;
|
||||
byte size_buf[WEBP_TAG_SIZE];
|
||||
|
||||
@ -294,7 +294,7 @@ void WebPImage::doWriteMetadata(BasicIo& outIo) {
|
||||
io_->seek(+1, BasicIo::cur); // skip pad
|
||||
|
||||
if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_VP8X)) {
|
||||
enforce(size_u32 >= 1, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(size_u32 >= 1, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
if (has_icc) {
|
||||
const uint8_t x = payload.read_uint8(0);
|
||||
payload.write_uint8(0, x | WEBP_VP8X_ICC_BIT);
|
||||
@ -477,7 +477,7 @@ void WebPImage::readMetadata() {
|
||||
io_->readOrThrow(data, WEBP_TAG_SIZE * 3, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
|
||||
const uint32_t filesize = Safe::add(Exiv2::getULong(data + WEBP_TAG_SIZE, littleEndian), 8U);
|
||||
enforce(filesize <= io_->size(), Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(filesize <= io_->size(), Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
|
||||
WebPImage::decodeChunks(filesize);
|
||||
|
||||
@ -500,15 +500,15 @@ void WebPImage::decodeChunks(uint32_t filesize) {
|
||||
const uint32_t size = Exiv2::getULong(size_buff, littleEndian);
|
||||
|
||||
// Check that `size` is within bounds.
|
||||
enforce(io_->tell() <= filesize, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
enforce(size <= (filesize - io_->tell()), Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(io_->tell() <= filesize, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(size <= (filesize - io_->tell()), Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
|
||||
DataBuf payload(size);
|
||||
|
||||
if (payload.empty()) {
|
||||
io_->seek(size, BasicIo::cur);
|
||||
} else if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_VP8X) && !has_canvas_data) {
|
||||
enforce(size >= 10, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(size >= 10, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
|
||||
has_canvas_data = true;
|
||||
byte size_buf[WEBP_TAG_SIZE];
|
||||
@ -525,7 +525,7 @@ void WebPImage::decodeChunks(uint32_t filesize) {
|
||||
size_buf[3] = 0;
|
||||
pixelHeight_ = Exiv2::getULong(size_buf, littleEndian) + 1;
|
||||
} else if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_VP8) && !has_canvas_data) {
|
||||
enforce(size >= 10, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(size >= 10, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
|
||||
has_canvas_data = true;
|
||||
io_->readOrThrow(payload.data(), payload.size(), Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
@ -543,7 +543,7 @@ void WebPImage::decodeChunks(uint32_t filesize) {
|
||||
size_buf[3] = 0;
|
||||
pixelHeight_ = Exiv2::getULong(size_buf, littleEndian) & 0x3fff;
|
||||
} else if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_VP8L) && !has_canvas_data) {
|
||||
enforce(size >= 5, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(size >= 5, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
|
||||
has_canvas_data = true;
|
||||
byte size_buf_w[2];
|
||||
@ -562,7 +562,7 @@ void WebPImage::decodeChunks(uint32_t filesize) {
|
||||
size_buf_h[1] = ((size_buf_h[1] >> 6) & 0x3) | ((size_buf_h[2] & 0xFU) << 0x2);
|
||||
pixelHeight_ = Exiv2::getUShort(size_buf_h, littleEndian) + 1;
|
||||
} else if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_ANMF) && !has_canvas_data) {
|
||||
enforce(size >= 12, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(size >= 12, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
|
||||
has_canvas_data = true;
|
||||
byte size_buf[WEBP_TAG_SIZE];
|
||||
@ -752,14 +752,14 @@ void WebPImage::inject_VP8X(BasicIo& iIo, bool has_xmp, bool has_exif, bool has_
|
||||
}
|
||||
|
||||
/* set width - stored in 24bits*/
|
||||
enforce(width > 0, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(width > 0, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
uint32_t w = width - 1;
|
||||
data[4] = w & 0xFF;
|
||||
data[5] = (w >> 8) & 0xFF;
|
||||
data[6] = (w >> 16) & 0xFF;
|
||||
|
||||
/* set height - stored in 24bits */
|
||||
enforce(width > 0, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
Internal::enforce(width > 0, Exiv2::ErrorCode::kerCorruptedMetadata);
|
||||
uint32_t h = height - 1;
|
||||
data[7] = h & 0xFF;
|
||||
data[8] = (h >> 8) & 0xFF;
|
||||
|
||||
@ -9,21 +9,23 @@
|
||||
|
||||
TEST(enforce, errMessageCanBeRetrievedFromErrorException) {
|
||||
try {
|
||||
enforce(false, Exiv2::ErrorCode::kerErrorMessage, "an error occurred");
|
||||
Exiv2::Internal::enforce(false, Exiv2::ErrorCode::kerErrorMessage, "an error occurred");
|
||||
} catch (const Exiv2::Error& e) {
|
||||
ASSERT_STREQ(e.what(), "an error occurred");
|
||||
}
|
||||
}
|
||||
|
||||
TEST(enforce, withTrueConditionDoesNotThrow) {
|
||||
ASSERT_NO_THROW(enforce(true, Exiv2::ErrorCode::kerErrorMessage));
|
||||
ASSERT_NO_THROW(Exiv2::Internal::enforce(true, Exiv2::ErrorCode::kerErrorMessage));
|
||||
}
|
||||
|
||||
TEST(enforce, withFalseConditionThrows) {
|
||||
ASSERT_THROW(enforce(false, Exiv2::ErrorCode::kerErrorMessage), Exiv2::Error);
|
||||
ASSERT_THROW(enforce(false, Exiv2::ErrorCode::kerErrorMessage, "error message"), Exiv2::Error);
|
||||
ASSERT_THROW(enforce(false, Exiv2::ErrorCode::kerDataSourceOpenFailed, "path", "strerror"), Exiv2::Error);
|
||||
ASSERT_THROW(enforce(false, Exiv2::ErrorCode::kerCallFailed, "path", "strerror", "function"), Exiv2::Error);
|
||||
ASSERT_THROW(enforce(false, Exiv2::ErrorCode::kerMallocFailed), Exiv2::Error);
|
||||
ASSERT_THROW(enforce<std::overflow_error>(false, "error message"), std::overflow_error);
|
||||
ASSERT_THROW(Exiv2::Internal::enforce(false, Exiv2::ErrorCode::kerErrorMessage), Exiv2::Error);
|
||||
ASSERT_THROW(Exiv2::Internal::enforce(false, Exiv2::ErrorCode::kerErrorMessage, "error message"), Exiv2::Error);
|
||||
ASSERT_THROW(Exiv2::Internal::enforce(false, Exiv2::ErrorCode::kerDataSourceOpenFailed, "path", "strerror"),
|
||||
Exiv2::Error);
|
||||
ASSERT_THROW(Exiv2::Internal::enforce(false, Exiv2::ErrorCode::kerCallFailed, "path", "strerror", "function"),
|
||||
Exiv2::Error);
|
||||
ASSERT_THROW(Exiv2::Internal::enforce(false, Exiv2::ErrorCode::kerMallocFailed), Exiv2::Error);
|
||||
ASSERT_THROW(Exiv2::Internal::enforce<std::overflow_error>(false, "error message"), std::overflow_error);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user