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

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

@ -620,7 +620,7 @@ void BmffImage::printStructure(std::ostream& out, Exiv2::PrintStructureOption op
break; // do nothing
case kpsIccProfile: {
out.write(iccProfile_.c_str(), iccProfile_.size());
out.write(iccProfile_.empty() ? nullptr : iccProfile_.c_str(), iccProfile_.size());
} break;
#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);
// 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());
ed->copy(buf.data(), pHead->byteOrder());
pHead->add(pCrwMapping->crwTagId_, pCrwMapping->crwDir_, std::move(buf));

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

@ -56,6 +56,7 @@ void PngChunk::decodeTXTChunk(Image* pImage, const DataBuf& data, TxtChunkType t
#ifdef EXIV2_DEBUG_MESSAGES
std::cout << "Exiv2::PngChunk::decodeTXTChunk: TXT chunk data: " << std::string(arr.c_str(), arr.size()) << std::endl;
#endif
if (!key.empty())
parseChunkContent(pImage, key.c_data(), key.size(), arr);
}
@ -558,8 +559,10 @@ DataBuf PngChunk::readRawProfile(const DataBuf& text, bool iTXt) {
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
size_t nibbles = length * 2;

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

@ -259,13 +259,15 @@ void RafImage::readMetadata() {
if (io_->seek(jpg_img_off + 12, BasicIo::beg) != 0)
throw Error(ErrorCode::kerFailedToReadImageData);
if (!buf.empty()) {
io_->read(buf.data(), buf.size());
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.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 /*dataIdx*/, uint32_t& /*imageIdx*/) {
if (!pValue_)
if (!pValue_ || pValue_->size() == 0)
return 0;
DataBuf buf(pValue_->size());
@ -1182,6 +1182,7 @@ uint32_t TiffDataEntry::doWriteData(IoWrapper& ioWrapper, ByteOrder /*byteOrder*
return 0;
DataBuf buf = pValue()->dataArea();
if (!buf.empty())
ioWrapper.write(buf.c_data(), buf.size());
// Align data to word boundary
uint32_t align = (buf.size() & 1);

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

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

Loading…
Cancel
Save