Fixing bad usages of DataBuf (when it is empty)

main
Luis Díaz Más 3 years ago
parent 4a4a8c544c
commit c3d0100d48

@ -170,8 +170,8 @@ int setModeAndPrintStructure(Exiv2::PrintStructureOption option, const std::stri
if (binary && option == Exiv2::kpsIccProfile) { if (binary && option == Exiv2::kpsIccProfile) {
std::stringstream output(std::stringstream::out | std::stringstream::binary); std::stringstream output(std::stringstream::out | std::stringstream::binary);
result = printStructure(output, option, path); result = printStructure(output, option, path);
if (result == 0) { std::string str = output.str();
std::string str = output.str(); if (result == 0 && !str.empty()) {
Exiv2::DataBuf iccProfile(str.size()); Exiv2::DataBuf iccProfile(str.size());
Exiv2::DataBuf ascii(str.size() * 3 + 1); Exiv2::DataBuf ascii(str.size() * 3 + 1);
ascii.write_uint8(str.size() * 3, 0); ascii.write_uint8(str.size() * 3, 0);
@ -549,9 +549,11 @@ bool Print::printMetadatum(const Exiv2::Metadatum& md, const Exiv2::Image* pImag
if (Params::instance().printItems_ & Params::prHex) { if (Params::instance().printItems_ & Params::prHex) {
if (!first) if (!first)
std::cout << std::endl; std::cout << std::endl;
Exiv2::DataBuf buf(md.size()); if (md.size() > 0) {
md.copy(buf.data(), pImage->byteOrder()); Exiv2::DataBuf buf(md.size());
Exiv2::hexdump(std::cout, buf.c_data(), buf.size()); md.copy(buf.data(), pImage->byteOrder());
Exiv2::hexdump(std::cout, buf.c_data(), buf.size());
}
} }
std::cout << std::endl; std::cout << std::endl;
return true; return true;

@ -1,4 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
// Sample program showing how to add, modify and delete Exif metadata. // Sample program showing how to add, modify and delete Exif metadata.
#include <exiv2/exiv2.hpp> #include <exiv2/exiv2.hpp>

@ -620,7 +620,7 @@ void BmffImage::printStructure(std::ostream& out, Exiv2::PrintStructureOption op
break; // do nothing break; // do nothing
case kpsIccProfile: { case kpsIccProfile: {
out.write(iccProfile_.c_str(), iccProfile_.size()); out.write(iccProfile_.empty() ? nullptr : iccProfile_.c_str(), iccProfile_.size());
} break; } break;
#ifdef EXV_HAVE_XMP_TOOLKIT #ifdef EXV_HAVE_XMP_TOOLKIT

@ -853,7 +853,7 @@ void CrwMap::encodeBasic(const Image& image, const CrwMapping* pCrwMapping, Ciff
auto ed = image.exifData().findKey(ek); auto ed = image.exifData().findKey(ek);
// Set the new value or remove the entry // Set the new value or remove the entry
if (ed != image.exifData().end()) { if (ed != image.exifData().end() && ed->size() > 0) {
DataBuf buf(ed->size()); DataBuf buf(ed->size());
ed->copy(buf.data(), pHead->byteOrder()); ed->copy(buf.data(), pHead->byteOrder());
pHead->add(pCrwMapping->crwTagId_, pCrwMapping->crwDir_, std::move(buf)); pHead->add(pCrwMapping->crwTagId_, pCrwMapping->crwDir_, std::move(buf));

@ -184,8 +184,9 @@ void JpegBase::readMetadata() {
#ifdef EXIV2_DEBUG_MESSAGES #ifdef EXIV2_DEBUG_MESSAGES
std::cerr << "Found app13 segment, size = " << size << "\n"; std::cerr << "Found app13 segment, size = " << size << "\n";
#endif #endif
// Append to psBlob if (buf.size() > 16) { // Append to psBlob
append(psBlob, buf.c_data(16), size - 16); append(psBlob, buf.c_data(16), size - 16);
}
// Check whether psBlob is complete // Check whether psBlob is complete
if (!psBlob.empty() && Photoshop::valid(&psBlob[0], psBlob.size())) { if (!psBlob.empty() && Photoshop::valid(&psBlob[0], psBlob.size())) {
--search; --search;
@ -745,9 +746,9 @@ void JpegBase::doWriteMetadata(BasicIo& outIo) {
bo = littleEndian; bo = littleEndian;
setByteOrder(bo); setByteOrder(bo);
} }
WriteMethod wm = ExifParser::encode(blob, rawExif.c_data(), rawExif.size(), bo, exifData_); const byte* pExifData = rawExif.empty() ? nullptr : rawExif.c_data();
const byte* pExifData = rawExif.c_data();
size_t exifSize = rawExif.size(); size_t exifSize = rawExif.size();
WriteMethod wm = ExifParser::encode(blob, pExifData, exifSize, bo, exifData_);
if (wm == wmIntrusive) { if (wm == wmIntrusive) {
pExifData = !blob.empty() ? &blob[0] : nullptr; pExifData = !blob.empty() ? &blob[0] : nullptr;
exifSize = blob.size(); exifSize = blob.size();
@ -844,7 +845,7 @@ void JpegBase::doWriteMetadata(BasicIo& outIo) {
// IPTC block if there is no new IPTC data to write // IPTC block if there is no new IPTC data to write
DataBuf newPsData = Photoshop::setIptcIrb(!psBlob.empty() ? psBlob.data() : nullptr, psBlob.size(), iptcData_); DataBuf newPsData = Photoshop::setIptcIrb(!psBlob.empty() ? psBlob.data() : nullptr, psBlob.size(), iptcData_);
const long maxChunkSize = 0xffff - 16; const long maxChunkSize = 0xffff - 16;
const byte* chunkStart = newPsData.c_data(); const byte* chunkStart = newPsData.empty() ? nullptr : newPsData.c_data();
const byte* chunkEnd = newPsData.empty() ? nullptr : newPsData.c_data(newPsData.size() - 1); const byte* chunkEnd = newPsData.empty() ? nullptr : newPsData.c_data(newPsData.size() - 1);
while (chunkStart < chunkEnd) { while (chunkStart < chunkEnd) {
// Determine size of next chunk // Determine size of next chunk

@ -56,7 +56,8 @@ void PngChunk::decodeTXTChunk(Image* pImage, const DataBuf& data, TxtChunkType t
#ifdef EXIV2_DEBUG_MESSAGES #ifdef EXIV2_DEBUG_MESSAGES
std::cout << "Exiv2::PngChunk::decodeTXTChunk: TXT chunk data: " << std::string(arr.c_str(), arr.size()) << std::endl; std::cout << "Exiv2::PngChunk::decodeTXTChunk: TXT chunk data: " << std::string(arr.c_str(), arr.size()) << std::endl;
#endif #endif
parseChunkContent(pImage, key.c_data(), key.size(), arr); if (!key.empty())
parseChunkContent(pImage, key.c_data(), key.size(), arr);
} }
DataBuf PngChunk::decodeTXTChunk(const DataBuf& data, TxtChunkType type) { DataBuf PngChunk::decodeTXTChunk(const DataBuf& data, TxtChunkType type) {
@ -558,8 +559,10 @@ DataBuf PngChunk::readRawProfile(const DataBuf& text, bool iTXt) {
return {}; return {};
} }
// Copy profile, skipping white space and column 1 "=" signs if (info.empty()) // Early return
return info;
// Copy profile, skipping white space and column 1 "=" signs
unsigned char* dp = info.data(); // decode pointer unsigned char* dp = info.data(); // decode pointer
size_t nibbles = length * 2; size_t nibbles = length * 2;

@ -234,8 +234,10 @@ void PngImage::printStructure(std::ostream& out, PrintStructureOption option, in
} }
DataBuf buff(dataOffset); DataBuf buff(dataOffset);
bufRead = io_->read(buff.data(), dataOffset); if (dataOffset > 0) {
enforce(bufRead == dataOffset, ErrorCode::kerFailedToReadImageData); bufRead = io_->read(buff.data(), dataOffset);
enforce(bufRead == dataOffset, ErrorCode::kerFailedToReadImageData);
}
io_->seek(restore, BasicIo::beg); io_->seek(restore, BasicIo::beg);
// format output // format output
@ -426,7 +428,9 @@ void PngImage::readMetadata() {
if (chunkType == "IEND" || chunkType == "IHDR" || chunkType == "tEXt" || chunkType == "zTXt" || if (chunkType == "IEND" || chunkType == "IHDR" || chunkType == "tEXt" || chunkType == "zTXt" ||
chunkType == "eXIf" || chunkType == "iTXt" || chunkType == "iCCP") { chunkType == "eXIf" || chunkType == "iTXt" || chunkType == "iCCP") {
DataBuf chunkData(chunkLength); DataBuf chunkData(chunkLength);
readChunk(chunkData, *io_); // Extract chunk data. if (chunkLength > 0) {
readChunk(chunkData, *io_); // Extract chunk data.
}
if (chunkType == "IEND") { if (chunkType == "IEND") {
return; // Last chunk found: we stop parsing. return; // Last chunk found: we stop parsing.

@ -259,13 +259,15 @@ void RafImage::readMetadata() {
if (io_->seek(jpg_img_off + 12, BasicIo::beg) != 0) if (io_->seek(jpg_img_off + 12, BasicIo::beg) != 0)
throw Error(ErrorCode::kerFailedToReadImageData); throw Error(ErrorCode::kerFailedToReadImageData);
io_->read(buf.data(), buf.size()); if (!buf.empty()) {
if (io_->error() || io_->eof()) io_->read(buf.data(), buf.size());
throw Error(ErrorCode::kerFailedToReadImageData); if (io_->error() || io_->eof())
throw Error(ErrorCode::kerFailedToReadImageData);
}
io_->seek(0, BasicIo::beg); // rewind // io_->seek(0, BasicIo::beg); // rewind
ByteOrder bo = TiffParser::decode(exifData_, iptcData_, xmpData_, buf.c_data(), buf.size()); ByteOrder bo = TiffParser::decode(exifData_, iptcData_, xmpData_, buf.empty() ? nullptr : buf.c_data(), buf.size());
exifData_["Exif.Image2.JPEGInterchangeFormat"] = getULong(jpg_img_offset, bigEndian); exifData_["Exif.Image2.JPEGInterchangeFormat"] = getULong(jpg_img_offset, bigEndian);
exifData_["Exif.Image2.JPEGInterchangeFormatLength"] = getULong(jpg_img_length, bigEndian); exifData_["Exif.Image2.JPEGInterchangeFormatLength"] = getULong(jpg_img_length, bigEndian);

@ -976,7 +976,7 @@ uint32_t TiffDirectory::writeDirEntry(IoWrapper& ioWrapper, ByteOrder byteOrder,
uint32_t TiffEntryBase::doWrite(IoWrapper& ioWrapper, ByteOrder byteOrder, int64_t /*offset*/, uint32_t /*valueIdx*/, uint32_t TiffEntryBase::doWrite(IoWrapper& ioWrapper, ByteOrder byteOrder, int64_t /*offset*/, uint32_t /*valueIdx*/,
uint32_t /*dataIdx*/, uint32_t& /*imageIdx*/) { uint32_t /*dataIdx*/, uint32_t& /*imageIdx*/) {
if (!pValue_) if (!pValue_ || pValue_->size() == 0)
return 0; return 0;
DataBuf buf(pValue_->size()); DataBuf buf(pValue_->size());
@ -1182,7 +1182,8 @@ uint32_t TiffDataEntry::doWriteData(IoWrapper& ioWrapper, ByteOrder /*byteOrder*
return 0; return 0;
DataBuf buf = pValue()->dataArea(); DataBuf buf = pValue()->dataArea();
ioWrapper.write(buf.c_data(), buf.size()); if (!buf.empty())
ioWrapper.write(buf.c_data(), buf.size());
// Align data to word boundary // Align data to word boundary
uint32_t align = (buf.size() & 1); uint32_t align = (buf.size() & 1);
if (align) if (align)

@ -162,10 +162,12 @@ void WebPImage::doWriteMetadata(BasicIo& outIo) {
// Check that `size_u32` is safe to cast to `long`. // Check that `size_u32` is safe to cast to `long`.
enforce(size_u32 <= std::numeric_limits<uint32_t>::max(), Exiv2::ErrorCode::kerCorruptedMetadata); enforce(size_u32 <= std::numeric_limits<uint32_t>::max(), Exiv2::ErrorCode::kerCorruptedMetadata);
DataBuf payload(size_u32); DataBuf payload(size_u32);
io_->readOrThrow(payload.data(), payload.size(), Exiv2::ErrorCode::kerCorruptedMetadata); if (!payload.empty()) {
if (payload.size() % 2) { io_->readOrThrow(payload.data(), payload.size(), Exiv2::ErrorCode::kerCorruptedMetadata);
byte c = 0; if (payload.size() % 2) {
io_->readOrThrow(&c, 1, Exiv2::ErrorCode::kerCorruptedMetadata); byte c = 0;
io_->readOrThrow(&c, 1, Exiv2::ErrorCode::kerCorruptedMetadata);
}
} }
/* Chunk with information about features /* Chunk with information about features
@ -528,7 +530,9 @@ void WebPImage::decodeChunks(long filesize) {
DataBuf payload(size); DataBuf payload(size);
if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_VP8X) && !has_canvas_data) { 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); enforce(size >= 10, Exiv2::ErrorCode::kerCorruptedMetadata);
has_canvas_data = true; has_canvas_data = true;

@ -14,8 +14,7 @@ class WebPImageGetHeaderOffset(metaclass=CaseMeta):
commands = ["$exiv2 $filename1"] commands = ["$exiv2 $filename1"]
stdout = [""] stdout = [""]
stderr = [ stderr = [
"""Warning: Failed to decode Exif metadata. """Exiv2 exception in print action for file $filename1:
Exiv2 exception in print action for file $filename1:
$kerCorruptedMetadata $kerCorruptedMetadata
""" """
] ]

Loading…
Cancel
Save