Change return type of BasicIo::tell() to size_t.

main
Kevin Backhouse 3 years ago
parent 7ebf2a184e
commit ad4e13b827
No known key found for this signature in database
GPG Key ID: 9DD01852EE40366E

@ -198,10 +198,9 @@ class EXIV2API BasicIo {
//@{
/*!
@brief Get the current IO position.
@return Offset from the start of IO if successful;<BR>
-1 if failure;
@return Offset from the start of IO
*/
[[nodiscard]] virtual long tell() const = 0;
[[nodiscard]] virtual size_t tell() const = 0;
/*!
@brief Get the current size of the IO source in bytes.
@return Size of the IO source in bytes;<BR>
@ -439,10 +438,9 @@ class EXIV2API FileIo : public BasicIo {
//@{
/*!
@brief Get the current file position.
@return Offset from the start of the file if successful;<BR>
-1 if failure;
@return Offset from the start of the file
*/
[[nodiscard]] long tell() const override;
[[nodiscard]] size_t tell() const override;
/*!
@brief Flush any buffered writes and get the current file size
in bytes.
@ -624,7 +622,7 @@ class EXIV2API MemIo : public BasicIo {
@brief Get the current IO position.
@return Offset from the start of the memory block
*/
[[nodiscard]] long tell() const override;
[[nodiscard]] size_t tell() const override;
/*!
@brief Get the current memory buffer size in bytes.
@return Size of the in memory data in bytes;<BR>
@ -874,7 +872,7 @@ class EXIV2API RemoteIo : public BasicIo {
@brief Get the current IO position.
@return Offset from the start of the memory block
*/
[[nodiscard]] long tell() const override;
[[nodiscard]] size_t tell() const override;
/*!
@brief Get the current memory buffer size in bytes.
@return Size of the in memory data in bytes;<BR>

@ -122,13 +122,13 @@ class EXIV2API BmffImage : public Image {
@return address of next box
@warning This function should only be called by readMetadata()
*/
long boxHandler(std::ostream& out, Exiv2::PrintStructureOption option, long pbox_end, int depth);
uint64_t boxHandler(std::ostream& out, Exiv2::PrintStructureOption option, uint64_t pbox_end, int depth);
[[nodiscard]] static std::string indent(int i) {
return std::string(2 * i, ' ');
}
uint32_t fileType_{0};
std::set<uint64_t> visits_;
std::set<size_t> visits_;
uint64_t visits_max_{0};
uint16_t unknownID_{0xffff};
uint16_t exifID_{0xffff};
@ -140,7 +140,7 @@ class EXIV2API BmffImage : public Image {
/*!
@brief box utilities
*/
static std::string toAscii(long n);
static std::string toAscii(uint32_t n);
std::string boxName(uint32_t box);
static bool superBox(uint32_t box);
static bool fullBox(uint32_t box);

@ -63,12 +63,13 @@ class EXIV2API WebPImage : public Image {
private:
void doWriteMetadata(BasicIo& outIo);
//! @name NOT Implemented
//@{
static long getHeaderOffset(const byte* data, size_t data_size, const byte* header, size_t header_size);
//! Finds the offset of header in data. Returns std::string::npos if the header isn't found.
static size_t getHeaderOffset(const byte* data, size_t data_size, const byte* header, size_t header_size);
static bool equalsWebPTag(Exiv2::DataBuf& buf, const char* str);
void debugPrintHex(byte* data, long size);
void decodeChunks(long filesize);
void debugPrintHex(byte* data, size_t size);
void decodeChunks(uint32_t filesize);
void inject_VP8X(BasicIo& iIo, bool has_xmp, bool has_exif, bool has_alpha, bool has_icc, int width, int height);
/* Misc. */
static constexpr byte WEBP_PAD_ODD = 0;

@ -458,8 +458,10 @@ int FileIo::seek(int64_t offset, Position pos) {
#endif
}
long FileIo::tell() const {
return std::ftell(p_->fp_);
size_t FileIo::tell() const {
const long pos = std::ftell(p_->fp_);
enforce(pos >= 0, ErrorCode::kerInputDataReadFailed);
return static_cast<size_t>(pos);
}
size_t FileIo::size() const {
@ -786,8 +788,8 @@ int MemIo::munmap() {
return 0;
}
long MemIo::tell() const {
return static_cast<long>(p_->idx_);
size_t MemIo::tell() const {
return p_->idx_;
}
size_t MemIo::size() const {
@ -1341,8 +1343,8 @@ int RemoteIo::munmap() {
return 0;
}
long RemoteIo::tell() const {
return static_cast<long>(p_->idx_);
size_t RemoteIo::tell() const {
return p_->idx_;
}
size_t RemoteIo::size() const {

@ -74,7 +74,7 @@ BmffImage::BmffImage(BasicIo::UniquePtr io, bool /* create */) :
Image(ImageType::bmff, mdExif | mdIptc | mdXmp, std::move(io)) {
} // BmffImage::BmffImage
std::string BmffImage::toAscii(long n) {
std::string BmffImage::toAscii(uint32_t n) {
const auto p = reinterpret_cast<const char*>(&n);
std::string result;
for (int i = 0; i < 4; i++) {
@ -152,9 +152,9 @@ std::string BmffImage::uuidName(Exiv2::DataBuf& uuid) {
return result;
}
long BmffImage::boxHandler(std::ostream& out /* = std::cout*/, Exiv2::PrintStructureOption option /* = kpsNone */,
long pbox_end, int depth) {
long address = io_->tell();
uint64_t BmffImage::boxHandler(std::ostream& out /* = std::cout*/, Exiv2::PrintStructureOption option /* = kpsNone */,
uint64_t pbox_end, int depth) {
const size_t address = io_->tell();
// never visit a box twice!
if (depth == 0)
visits_.clear();
@ -198,22 +198,22 @@ long BmffImage::boxHandler(std::ostream& out /* = std::cout*/, Exiv2::PrintStruc
}
// read data in box and restore file position
long restore = io_->tell();
const size_t restore = io_->tell();
enforce(box_length >= hdrsize, Exiv2::ErrorCode::kerCorruptedMetadata);
enforce(box_length - hdrsize <= static_cast<uint64_t>(pbox_end - restore), Exiv2::ErrorCode::kerCorruptedMetadata);
enforce(box_length - hdrsize <= pbox_end - restore, Exiv2::ErrorCode::kerCorruptedMetadata);
const auto buffer_size = static_cast<size_t>(box_length - hdrsize);
const auto buffer_size = box_length - hdrsize;
if (skipBox(box_type)) {
if (bTrace) {
out << std::endl;
}
// The enforce() above checks that restore + buffer_size won't
// exceed pbox_end, and by implication, won't exceed LONG_MAX
return restore + static_cast<long>(buffer_size);
return restore + buffer_size;
}
DataBuf data(buffer_size);
const long box_end = restore + static_cast<long>(data.size());
DataBuf data(static_cast<size_t>(buffer_size));
const size_t box_end = restore + data.size();
io_->read(data.data(), data.size());
io_->seek(restore, BasicIo::beg);
@ -478,26 +478,25 @@ long BmffImage::boxHandler(std::ostream& out /* = std::cout*/, Exiv2::PrintStruc
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 <= std::numeric_limits<uint64_t>::max(), ErrorCode::kerCorruptedMetadata);
enforce(length <= std::numeric_limits<uint64_t>::max(), 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);
// read and parse exif data
long restore = io_->tell();
const size_t restore = io_->tell();
DataBuf exif(static_cast<size_t>(length));
io_->seek(static_cast<long>(start), BasicIo::beg);
io_->seek(static_cast<int64_t>(start), BasicIo::beg);
if (exif.size() > 8 && io_->read(exif.data(), exif.size()) == exif.size()) {
// hunt for "II" or "MM"
long eof = 0xffffffff; // impossible value for punt
long punt = eof;
const size_t eof = std::numeric_limits<size_t>::max(); // impossible value for punt
size_t punt = eof;
for (size_t i = 0; i < exif.size() - 8 && punt == eof; i += 2) {
if (exif.read_uint8(i) == exif.read_uint8(i + 1))
if (exif.read_uint8(i) == 'I' || exif.read_uint8(i) == 'M')
punt = static_cast<long>(i);
punt = i;
}
if (punt != eof) {
Internal::TiffParserWorker::decode(exifData(), iptcData(), xmpData(), exif.c_data(punt),
static_cast<uint32_t>(exif.size() - punt), root_tag,
Internal::TiffMapping::findDecoder);
Internal::TiffParserWorker::decode(exifData(), iptcData(), xmpData(), exif.c_data(punt), exif.size() - punt,
root_tag, Internal::TiffMapping::findDecoder);
}
}
io_->seek(restore, BasicIo::beg);
@ -506,7 +505,7 @@ 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<uint64_t>::max(), ErrorCode::kerCorruptedMetadata);
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());
@ -524,8 +523,8 @@ void BmffImage::parseXmp(uint64_t length, uint64_t start) {
enforce(start <= io_->size(), ErrorCode::kerCorruptedMetadata);
enforce(length <= io_->size() - start, ErrorCode::kerCorruptedMetadata);
long restore = io_->tell();
io_->seek(static_cast<long>(start), BasicIo::beg);
const size_t restore = io_->tell();
io_->seek(static_cast<int64_t>(start), BasicIo::beg);
auto lengthSizeT = static_cast<size_t>(length);
DataBuf xmp(lengthSizeT + 1);
@ -547,9 +546,8 @@ void BmffImage::parseXmp(uint64_t length, uint64_t start) {
void BmffImage::parseCr3Preview(DataBuf& data, std::ostream& out, bool bTrace, uint8_t version, size_t width_offset,
size_t height_offset, size_t size_offset, size_t relative_position) {
// Derived from https://github.com/lclevy/canon_cr3
long here = io_->tell();
enforce(here >= 0 && here <= std::numeric_limits<long>::max() - static_cast<long>(relative_position),
ErrorCode::kerCorruptedMetadata);
const size_t here = io_->tell();
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_);
@ -600,8 +598,8 @@ void BmffImage::readMetadata() {
exifID_ = unknownID_;
xmpID_ = unknownID_;
long address = 0;
const auto file_end = static_cast<long>(io_->size());
uint64_t address = 0;
const auto file_end = io_->size();
while (address < file_end) {
io_->seek(address, BasicIo::beg);
address = boxHandler(std::cout, kpsNone, file_end, 0);
@ -635,8 +633,8 @@ void BmffImage::printStructure(std::ostream& out, Exiv2::PrintStructureOption op
openOrThrow();
IoCloser closer(*io_);
long address = 0;
const auto file_end = static_cast<long>(io_->size());
uint64_t address = 0;
const auto file_end = io_->size();
while (address < file_end) {
io_->seek(address, BasicIo::beg);
address = boxHandler(out, option, file_end, depth);
@ -682,7 +680,7 @@ bool isBmffType(BasicIo& iIo, bool advance) {
bool const is_video = (buf[8] == 'q' && buf[9] == 't' && buf[10] == ' ' && buf[11] == ' ');
bool matched = is_jxl || (is_ftyp && !is_video);
if (!advance || !matched) {
iIo.seek(static_cast<long>(0), BasicIo::beg);
iIo.seek(0, BasicIo::beg);
}
return matched;
}

@ -11,6 +11,7 @@
#include "config.h"
#include "basicio.hpp"
#include "enforce.hpp"
#include "epsimage.hpp"
#include "error.hpp"
#include "futils.hpp"
@ -101,13 +102,8 @@ void writeTemp(BasicIo& tempIo, const std::string& data) {
//! Get the current write position of temp file, taking care of errors
uint32_t posTemp(const BasicIo& tempIo) {
const long pos = tempIo.tell();
if (pos == -1) {
#ifndef SUPPRESS_WARNINGS
EXV_WARNING << "Internal error while determining current write position in temporary file.\n";
#endif
throw Error(ErrorCode::kerImageWriteFailed);
}
const size_t pos = tempIo.tell();
enforce(pos <= std::numeric_limits<uint32_t>::max(), ErrorCode::kerImageWriteFailed);
return static_cast<uint32_t>(pos);
}
@ -1167,7 +1163,7 @@ bool isEpsType(BasicIo& iIo, bool advance) {
bufSize = i.size();
}
}
const long restore = iIo.tell(); // save
const size_t restore = iIo.tell(); // save
DataBuf buf = iIo.read(bufSize);
if (iIo.error() || buf.size() != bufSize) {
iIo.seek(restore, BasicIo::beg);

@ -287,7 +287,7 @@ static bool typeValid(uint16_t type) {
return type >= 1 && type <= 13;
}
static std::set<long> visits; // #547
static std::set<size_t> visits; // #547
void Image::printIFDStructure(BasicIo& io, std::ostream& out, Exiv2::PrintStructureOption option, size_t start,
bool bSwap, char c, int depth) {
@ -370,7 +370,7 @@ void Image::printIFDStructure(BasicIo& io, std::ostream& out, Exiv2::PrintStruct
const bool bOffsetIsPointer = count_x_size > 4;
if (bOffsetIsPointer) { // read into buffer
const long restore = io.tell(); // save
const size_t restore = io.tell(); // save
io.seekOrThrow(offset, BasicIo::beg, ErrorCode::kerCorruptedMetadata); // position
io.readOrThrow(buf.data(), count_x_size, ErrorCode::kerCorruptedMetadata); // read
io.seekOrThrow(restore, BasicIo::beg, ErrorCode::kerCorruptedMetadata); // restore
@ -410,7 +410,7 @@ void Image::printIFDStructure(BasicIo& io, std::ostream& out, Exiv2::PrintStruct
if (option == kpsRecursive && (tag == 0x8769 /* ExifTag */ || tag == 0x014a /*SubIFDs*/ || type == tiffIfd)) {
for (size_t k = 0; k < count; k++) {
const long restore = io.tell();
const size_t restore = io.tell();
offset = byteSwap4(buf, k * size, bSwap);
printIFDStructure(io, out, option, offset, bSwap, c, depth);
io.seekOrThrow(restore, BasicIo::beg, ErrorCode::kerCorruptedMetadata);
@ -421,7 +421,7 @@ void Image::printIFDStructure(BasicIo& io, std::ostream& out, Exiv2::PrintStruct
throw Error(ErrorCode::kerCorruptedMetadata);
}
const long restore = io.tell();
const size_t restore = io.tell();
io.seekOrThrow(offset, BasicIo::beg, ErrorCode::kerCorruptedMetadata); // position
std::vector<byte> bytes(count); // allocate memory
// TODO: once we have C++11 use bytes.data()
@ -431,7 +431,7 @@ void Image::printIFDStructure(BasicIo& io, std::ostream& out, Exiv2::PrintStruct
IptcData::printStructure(out, makeSliceUntil(bytes.data(), count), depth);
}
} else if (option == kpsRecursive && tag == 0x927c /* MakerNote */ && count > 10) {
const long restore = io.tell(); // save
const size_t restore = io.tell(); // save
uint32_t jump = 10;
byte bytes[20];

@ -151,7 +151,7 @@ void Jp2Image::readMetadata() {
while (io_->read(reinterpret_cast<byte*>(&box), boxHSize) == boxHSize) {
boxes_check(boxesCount++, boxem);
long position = io_->tell();
const size_t position = io_->tell();
box.length = getLong(reinterpret_cast<byte*>(&box.length), bigEndian);
box.type = getLong(reinterpret_cast<byte*>(&box.type), bigEndian);
#ifdef EXIV2_DEBUG_MESSAGES
@ -191,7 +191,7 @@ void Jp2Image::readMetadata() {
#ifdef EXIV2_DEBUG_MESSAGES
std::cout << "Exiv2::Jp2Image::readMetadata: JP2Header box found" << std::endl;
#endif
long restore = io_->tell();
size_t restore = io_->tell();
while (io_->read(reinterpret_cast<byte*>(&subBox), boxHSize) == boxHSize && subBox.length) {
boxes_check(boxesCount++, boxem);
@ -210,7 +210,7 @@ void Jp2Image::readMetadata() {
<< "Color data found" << std::endl;
#endif
const long pad = 3; // 3 padding bytes 2 0 0
const size_t pad = 3; // 3 padding bytes 2 0 0
const size_t data_length = Safe::add(subBox.length, 8u);
// data_length makes no sense if it is larger than the rest of the file
if (data_length > io_->size() - io_->tell()) {
@ -291,13 +291,14 @@ void Jp2Image::readMetadata() {
// Find the position of Exif header in bytes array.
const char a = rawData.read_uint8(0);
const char b = rawData.read_uint8(1);
long pos = (a == b && (a == 'I' || a == 'M')) ? 0 : -1;
const size_t notfound = std::numeric_limits<size_t>::max();
size_t pos = (a == b && (a == 'I' || a == 'M')) ? 0 : notfound;
// #1242 Forgive having Exif\0\0 in rawData.pData_
std::array<byte, 6> exifHeader{0x45, 0x78, 0x69, 0x66, 0x00, 0x00};
for (size_t i = 0; pos < 0 && i < (rawData.size() - exifHeader.size()); i++) {
for (size_t i = 0; pos == notfound && i < (rawData.size() - exifHeader.size()); i++) {
if (rawData.cmpBytes(i, exifHeader.data(), exifHeader.size()) == 0) {
pos = static_cast<long>(i + sizeof(exifHeader));
pos = i + sizeof(exifHeader);
#ifndef SUPPRESS_WARNINGS
EXV_WARNING << "Reading non-standard UUID-EXIF_bad box in " << io_->path() << std::endl;
#endif
@ -305,7 +306,7 @@ void Jp2Image::readMetadata() {
}
// If found it, store only these data at from this place.
if (pos >= 0) {
if (pos != notfound) {
#ifdef EXIV2_DEBUG_MESSAGES
std::cout << "Exiv2::Jp2Image::readMetadata: Exif header found at position " << pos << std::endl;
#endif
@ -380,7 +381,7 @@ void Jp2Image::readMetadata() {
lastBoxTypeRead = box.type;
// Move to the next box.
io_->seek(static_cast<long>(position - boxHSize + box.length), BasicIo::beg);
io_->seek(static_cast<int64_t>(position - boxHSize + box.length), BasicIo::beg);
if (io_->error())
throw Error(ErrorCode::kerFailedToReadImageData);
}
@ -418,7 +419,7 @@ void Jp2Image::printStructure(std::ostream& out, PrintStructureOption option, in
while (box.length && box.type != kJp2BoxTypeClose &&
io_->read(reinterpret_cast<byte*>(&box), boxHSize) == boxHSize) {
long position = io_->tell();
const size_t position = io_->tell();
box.length = getLong(reinterpret_cast<byte*>(&box.length), bigEndian);
box.type = getLong(reinterpret_cast<byte*>(&box.type), bigEndian);
enforce(box.length <= boxHSize + io_->size() - io_->tell(), ErrorCode::kerCorruptedMetadata);
@ -454,7 +455,7 @@ void Jp2Image::printStructure(std::ostream& out, PrintStructureOption option, in
/// \todo All files shall contain one and only one Header box.
while (io_->read(reinterpret_cast<byte*>(&subBox), boxHSize) == boxHSize &&
io_->tell() < position + static_cast<long>(box.length)) // don't read beyond the box!
io_->tell() < position + box.length) // don't read beyond the box!
{
const size_t address = io_->tell() - boxHSize;
subBox.length = getLong(reinterpret_cast<byte*>(&subBox.length), bigEndian);
@ -571,7 +572,7 @@ void Jp2Image::printStructure(std::ostream& out, PrintStructureOption option, in
}
// Move to the next box.
io_->seek(static_cast<long>(position - boxHSize + box.length), BasicIo::beg);
io_->seek(static_cast<int64_t>(position - boxHSize + box.length), BasicIo::beg);
if (io_->error())
throw Error(ErrorCode::kerFailedToReadImageData);
if (bPrint)
@ -704,7 +705,7 @@ void Jp2Image::doWriteMetadata(BasicIo& outIo) {
byte boxUUIDtype[4];
DataBuf bheaderBuf(8);
while (io_->tell() < static_cast<long>(io_->size())) {
while (io_->tell() < io_->size()) {
#ifdef EXIV2_DEBUG_MESSAGES
std::cout << "Exiv2::Jp2Image::doWriteMetadata: Position: " << io_->tell() << " / " << io_->size() << std::endl;
#endif
@ -893,7 +894,7 @@ bool isJp2Type(BasicIo& iIo, bool advance) {
}
bool matched = (memcmp(buf, Jp2Signature.data(), Jp2Signature.size()) == 0);
if (!advance || !matched) {
iIo.seek(-static_cast<long>(Jp2Signature.size()), BasicIo::cur); // Return to original position
iIo.seek(-static_cast<int64_t>(Jp2Signature.size()), BasicIo::cur); // Return to original position
}
return matched;
}

@ -304,7 +304,7 @@ void JpegBase::printStructure(std::ostream& out, PrintStructureOption option, in
}
bool bPrint = option == kpsBasic || option == kpsRecursive;
std::vector<long> iptcDataSegs;
std::vector<size_t> iptcDataSegs;
if (bPrint || option == kpsXMP || option == kpsIccProfile || option == kpsIptcErase) {
// mnemonic for markers
@ -618,7 +618,7 @@ void JpegBase::doWriteMetadata(BasicIo& outIo) {
// Used to initialize search variables such as skipCom.
static const size_t notfound = std::numeric_limits<size_t>::max();
const long seek = io_->tell();
const size_t seek = io_->tell();
size_t count = 0;
size_t search = 0;
size_t insertPos = 0;
@ -809,7 +809,7 @@ void JpegBase::doWriteMetadata(BasicIo& outIo) {
tmpBuf[0] = 0xff;
tmpBuf[1] = app2_;
const long chunk_size = 256 * 256 - 40; // leave bytes for marker, header and padding
const size_t chunk_size = 256 * 256 - 40; // leave bytes for marker, header and padding
size_t size = iccProfile_.size();
if (size >= 255 * chunk_size)
throw Error(ErrorCode::kerTooLargeJpegSegment, "IccProfile");
@ -844,7 +844,7 @@ void JpegBase::doWriteMetadata(BasicIo& outIo) {
// Set the new IPTC IRB, keeps existing IRBs but removes the
// IPTC block if there is no new IPTC data to write
DataBuf newPsData = Photoshop::setIptcIrb(psBlob.data(), psBlob.size(), iptcData_);
const long maxChunkSize = 0xffff - 16;
const size_t maxChunkSize = 0xffff - 16;
const byte* chunkStart = newPsData.empty() ? nullptr : newPsData.c_data();
const byte* chunkEnd = newPsData.empty() ? nullptr : newPsData.c_data(newPsData.size() - 1);
while (chunkStart < chunkEnd) {
@ -853,7 +853,7 @@ void JpegBase::doWriteMetadata(BasicIo& outIo) {
if (chunkSize > maxChunkSize) {
chunkSize = maxChunkSize;
// Don't break at a valid IRB boundary
const auto writtenSize = static_cast<long>(chunkStart - newPsData.c_data());
const auto writtenSize = chunkStart - newPsData.c_data();
if (Photoshop::valid(newPsData.c_data(), writtenSize + chunkSize)) {
// Since an IRB has minimum size 12,
// (chunkSize - 8) can't be also a IRB boundary

@ -90,7 +90,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);
size_t size = headerSize + 8 - static_cast<size_t>(io_->tell());
size_t size = headerSize + 8 - io_->tell();
#ifdef EXIV2_DEBUG_MESSAGES
std::cout << "Exiv2::PgfImage::readMetadata: Found Image data (" << size << " bytes)\n";

@ -72,8 +72,8 @@ std::string PngImage::mimeType() const {
return "image/png";
}
static bool zlibToDataBuf(const byte* bytes, long length, DataBuf& result) {
uLongf uncompressedLen = length * 2; // just a starting point
static bool zlibToDataBuf(const byte* bytes, uLongf length, DataBuf& result) {
uLongf uncompressedLen = length; // just a starting point
int zlibResult = Z_BUF_ERROR;
do {
@ -101,7 +101,7 @@ static bool zlibToDataBuf(const byte* bytes, long length, DataBuf& result) {
return zlibResult == Z_OK;
}
static bool zlibToCompressed(const byte* bytes, long length, DataBuf& result) {
static bool zlibToCompressed(const byte* bytes, uLongf length, DataBuf& result) {
uLongf compressedLen = length; // just a starting point
int zlibResult = Z_BUF_ERROR;
@ -122,7 +122,7 @@ static bool zlibToCompressed(const byte* bytes, long length, DataBuf& result) {
return zlibResult == Z_OK;
}
static bool tEXtToDataBuf(const byte* bytes, long length, DataBuf& result) {
static bool tEXtToDataBuf(const byte* bytes, size_t length, DataBuf& result) {
static std::array<int, 256> value;
static bool bFirst = true;
if (bFirst) {
@ -137,21 +137,21 @@ static bool tEXtToDataBuf(const byte* bytes, long length, DataBuf& result) {
// calculate length and allocate result;
// count: number of \n in the header
long count = 0;
size_t count = 0;
// p points to the current position in the array bytes
const byte* p = bytes;
// header is '\nsomething\n number\n hex'
// => increment p until it points to the byte after the last \n
// p must stay within bounds of the bytes array!
while ((count < 3) && (p - bytes < length)) {
while (count < 3 && 0 < length) {
// length is later used for range checks of p => decrement it for each increment of p
--length;
if (*p++ == '\n') {
count++;
}
}
for (long i = 0; i < length; i++)
for (size_t i = 0; i < length; i++)
if (value[p[i]])
++count;
result.alloc((count + 1) / 2);
@ -160,7 +160,7 @@ static bool tEXtToDataBuf(const byte* bytes, long length, DataBuf& result) {
count = 0;
byte* r = result.data();
int n = 0; // nibble
for (long i = 0; i < length; i++) {
for (size_t i = 0; i < length; i++) {
if (value[p[i]]) {
int v = value[p[i]] - 1;
if (++count % 2)
@ -208,7 +208,7 @@ void PngImage::printStructure(std::ostream& out, PrintStructureOption option, in
DataBuf cheaderBuf(8);
while (!io_->eof() && ::strcmp(chType, "IEND") != 0) {
size_t address = io_->tell();
const size_t address = io_->tell();
size_t bufRead = io_->read(cheaderBuf.data(), cheaderBuf.size());
if (io_->error())
@ -223,8 +223,8 @@ void PngImage::printStructure(std::ostream& out, PrintStructureOption option, in
}
// test that we haven't hit EOF, or wanting to read excessive data
long restore = io_->tell();
if (restore == -1 || dataOffset > static_cast<uint32_t>(0x7FFFFFFF) || dataOffset > imgSize - restore) {
const size_t restore = io_->tell();
if (dataOffset > imgSize - restore) {
throw Exiv2::Error(ErrorCode::kerFailedToReadImageData);
}
@ -297,10 +297,11 @@ void PngImage::printStructure(std::ostream& out, PrintStructureOption option, in
// decode the chunk
bool bGood = false;
if (tEXt) {
bGood = tEXtToDataBuf(data.c_data(name_l), static_cast<long>(dataOffset - name_l), dataBuf);
bGood = tEXtToDataBuf(data.c_data(name_l), dataOffset - name_l, dataBuf);
}
if (zTXt || iCCP) {
bGood = zlibToDataBuf(data.c_data(name_l + 1), static_cast<long>(dataOffset - name_l - 1),
enforce(dataOffset - name_l - 1 <= std::numeric_limits<uLongf>::max(), ErrorCode::kerCorruptedMetadata);
bGood = zlibToDataBuf(data.c_data(name_l + 1), static_cast<uLongf>(dataOffset - name_l - 1),
dataBuf); // +1 = 'compressed' flag
}
if (iTXt) {
@ -407,8 +408,8 @@ void PngImage::readMetadata() {
// Decode chunk data length.
uint32_t chunkLength = cheaderBuf.read_uint32(0, Exiv2::bigEndian);
long pos = io_->tell();
if (pos == -1 || chunkLength > static_cast<uint32_t>(0x7FFFFFFF) || chunkLength > imgSize - pos) {
const size_t pos = io_->tell();
if (chunkLength > imgSize - pos) {
throw Exiv2::Error(ErrorCode::kerFailedToReadImageData);
}
@ -451,7 +452,7 @@ void PngImage::readMetadata() {
++iccOffset; // +1 = 'compressed' flag
enforce(iccOffset <= chunkLength, Exiv2::ErrorCode::kerCorruptedMetadata);
zlibToDataBuf(chunkData.c_data(iccOffset), chunkLength - iccOffset, iccProfile_);
zlibToDataBuf(chunkData.c_data(iccOffset), static_cast<uLongf>(chunkLength - iccOffset), iccProfile_);
#ifdef EXIV2_DEBUG_MESSAGES
std::cout << "Exiv2::PngImage::readMetadata: profile name: " << profileName_ << std::endl;
std::cout << "Exiv2::PngImage::readMetadata: iccProfile.size_ (uncompressed) : " << iccProfile_.size()
@ -594,7 +595,8 @@ void PngImage::doWriteMetadata(BasicIo& outIo) {
if (iccProfileDefined()) {
DataBuf compressed;
if (zlibToCompressed(iccProfile_.c_data(), static_cast<long>(iccProfile_.size()), compressed)) {
enforce(iccProfile_.size() <= std::numeric_limits<uLongf>::max(), ErrorCode::kerCorruptedMetadata);
if (zlibToCompressed(iccProfile_.c_data(), static_cast<uLongf>(iccProfile_.size()), compressed)) {
const auto nameLength = static_cast<uint32_t>(profileName_.size());
const uint32_t chunkLength = nameLength + 2 + static_cast<uint32_t>(compressed.size());
byte length[4];

@ -194,7 +194,7 @@ void PsdImage::readMetadata() {
throw Error(ErrorCode::kerNotAnImage, "Photoshop");
}
uint32_t resourceSize = getULong(buf, bigEndian);
uint32_t curOffset = io_->tell();
const size_t curOffset = io_->tell();
#ifdef EXIV2_DEBUG_MESSAGES
std::cerr << std::hex << "resourceId: " << resourceId << std::dec << " length: " << resourceSize << std::hex
@ -382,7 +382,7 @@ void PsdImage::doWriteMetadata(BasicIo& outIo) {
if (outIo.error())
throw Error(ErrorCode::kerImageWriteFailed);
uint32_t resLenOffset = io_->tell(); // remember for later update
const size_t resLenOffset = io_->tell(); // remember for later update
// Read length of all resource blocks from original PSD
if (io_->read(buf, 4) != 4)
@ -433,7 +433,7 @@ void PsdImage::doWriteMetadata(BasicIo& outIo) {
uint32_t resourceSize = getULong(buf, bigEndian);
uint32_t pResourceSize = (resourceSize + 1) & ~1; // padded resource size
uint32_t curOffset = io_->tell();
const size_t curOffset = io_->tell();
// Write IPTC_NAA resource block
if ((resourceId == kPhotoshopResourceID_IPTC_NAA || resourceId > kPhotoshopResourceID_IPTC_NAA) && !iptcDone) {

@ -103,7 +103,7 @@ bool isTgaType(BasicIo& iIo, bool /*advance*/) {
return true;
}
byte buf[26];
long curPos = iIo.tell();
const size_t curPos = iIo.tell();
if (curPos < 26)
return false;

@ -154,13 +154,11 @@ void WebPImage::doWriteMetadata(BasicIo& outIo) {
/* Verify for a VP8X Chunk First before writing in
case we have any exif or xmp data, also check
for any chunks with alpha frame/layer set */
while (!io_->eof() && static_cast<uint64_t>(io_->tell()) < filesize) {
while (!io_->eof() && io_->tell() < filesize) {
io_->readOrThrow(chunkId.data(), WEBP_TAG_SIZE, Exiv2::ErrorCode::kerCorruptedMetadata);
io_->readOrThrow(size_buff, WEBP_TAG_SIZE, Exiv2::ErrorCode::kerCorruptedMetadata);
const uint32_t size_u32 = Exiv2::getULong(size_buff, littleEndian);
// 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);
@ -286,15 +284,11 @@ void WebPImage::doWriteMetadata(BasicIo& outIo) {
}
io_->seek(12, BasicIo::beg);
while (!io_->eof() && static_cast<uint64_t>(io_->tell()) < filesize) {
while (!io_->eof() && io_->tell() < filesize) {
io_->readOrThrow(chunkId.data(), 4, Exiv2::ErrorCode::kerCorruptedMetadata);
io_->readOrThrow(size_buff, 4, Exiv2::ErrorCode::kerCorruptedMetadata);
const uint32_t size_u32 = Exiv2::getULong(size_buff, littleEndian);
// 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);
io_->readOrThrow(payload.data(), size_u32, Exiv2::ErrorCode::kerCorruptedMetadata);
if (io_->tell() % 2)
@ -438,19 +432,18 @@ void WebPImage::printStructure(std::ostream& out, PrintStructureOption option, i
}
io_->seek(0, BasicIo::beg); // rewind
while (!io_->eof() && static_cast<uint64_t>(io_->tell()) < filesize) {
auto offset = static_cast<uint64_t>(io_->tell());
while (!io_->eof() && io_->tell() < filesize) {
auto offset = io_->tell();
byte size_buff[WEBP_TAG_SIZE];
io_->read(chunkId.data(), WEBP_TAG_SIZE);
io_->read(size_buff, WEBP_TAG_SIZE);
long size = Exiv2::getULong(size_buff, littleEndian);
const uint32_t size = Exiv2::getULong(size_buff, littleEndian);
DataBuf payload(offset ? size : WEBP_TAG_SIZE); // header is different from chunks
io_->read(payload.data(), payload.size());
if (bPrint) {
out << Internal::indent(depth)
<< Internal::stringFormat(" %s | %8u | %8u | ", chunkId.c_str(), static_cast<uint32_t>(size),
static_cast<uint32_t>(offset))
<< Internal::stringFormat(" %s | %8u | %8u | ", chunkId.c_str(), size, static_cast<uint32_t>(offset))
<< Internal::binaryToString(makeSlice(payload, 0, payload.size() > 32 ? 32 : payload.size())) << std::endl;
}
@ -492,18 +485,14 @@ void WebPImage::readMetadata() {
io_->readOrThrow(data, WEBP_TAG_SIZE * 3, Exiv2::ErrorCode::kerCorruptedMetadata);
const uint32_t filesize_u32 = Safe::add(Exiv2::getULong(data + WEBP_TAG_SIZE, littleEndian), 8U);
enforce(filesize_u32 <= io_->size(), Exiv2::ErrorCode::kerCorruptedMetadata);
const uint32_t filesize = Safe::add(Exiv2::getULong(data + WEBP_TAG_SIZE, littleEndian), 8U);
enforce(filesize <= io_->size(), Exiv2::ErrorCode::kerCorruptedMetadata);
// Check that `filesize_u32` is safe to cast to `long`.
enforce(filesize_u32 <= static_cast<uint32_t>(std::numeric_limits<long>::max()),
Exiv2::ErrorCode::kerCorruptedMetadata);
WebPImage::decodeChunks(static_cast<long>(filesize_u32));
WebPImage::decodeChunks(filesize);
} // WebPImage::readMetadata
void WebPImage::decodeChunks(long filesize) {
void WebPImage::decodeChunks(uint32_t filesize) {
DataBuf chunkId(5);
byte size_buff[WEBP_TAG_SIZE];
bool has_canvas_data = false;
@ -517,12 +506,7 @@ void WebPImage::decodeChunks(long filesize) {
io_->readOrThrow(chunkId.data(), WEBP_TAG_SIZE, Exiv2::ErrorCode::kerCorruptedMetadata);
io_->readOrThrow(size_buff, WEBP_TAG_SIZE, Exiv2::ErrorCode::kerCorruptedMetadata);
const uint32_t size_u32 = Exiv2::getULong(size_buff, littleEndian);
// Check that `size_u32` is safe to cast to `long`.
enforce(size_u32 <= static_cast<uint32_t>(std::numeric_limits<long>::max()),
Exiv2::ErrorCode::kerCorruptedMetadata);
const auto size = static_cast<long>(size_u32);
const uint32_t size = Exiv2::getULong(size_buff, littleEndian);
// Check that `size` is within bounds.
enforce(io_->tell() <= filesize, Exiv2::ErrorCode::kerCorruptedMetadata);
@ -619,23 +603,23 @@ void WebPImage::decodeChunks(long filesize) {
bool s_header = false;
bool le_header = false;
bool be_header = false;
long pos = getHeaderOffset(payload.c_data(), payload.size(), reinterpret_cast<byte*>(&exifLongHeader), 4);
size_t pos = getHeaderOffset(payload.c_data(), payload.size(), reinterpret_cast<byte*>(&exifLongHeader), 4);
if (pos == -1) {
if (pos == std::string::npos) {
pos = getHeaderOffset(payload.c_data(), payload.size(), reinterpret_cast<byte*>(&exifLongHeader), 6);
if (pos != -1) {
if (pos != std::string::npos) {
s_header = true;
}
}
if (pos == -1) {
if (pos == std::string::npos) {
pos = getHeaderOffset(payload.c_data(), payload.size(), reinterpret_cast<byte*>(&exifTiffLEHeader), 3);
if (pos != -1) {
if (pos != std::string::npos) {
le_header = true;
}
}
if (pos == -1) {
if (pos == std::string::npos) {
pos = getHeaderOffset(payload.c_data(), payload.size(), reinterpret_cast<byte*>(&exifTiffBEHeader), 4);
if (pos != -1) {
if (pos != std::string::npos) {
be_header = true;
}
}
@ -666,11 +650,11 @@ void WebPImage::decodeChunks(long filesize) {
std::copy(payload.begin(), payload.end(), rawExifData.begin() + offset);
#ifdef EXIV2_DEBUG_MESSAGES
std::cout << "Display Hex Dump [size:" << static_cast<unsigned long>(sizePayload) << "]" << std::endl;
std::cout << "Display Hex Dump [size:" << sizePayload << "]" << std::endl;
std::cout << binaryToHex(rawExifData.c_data(), sizePayload);
#endif
if (pos != -1) {
if (pos != std::string::npos) {
XmpData xmpData;
ByteOrder bo = ExifParser::decode(exifData_, payload.c_data(pos), payload.size() - pos);
setByteOrder(bo);
@ -689,7 +673,7 @@ void WebPImage::decodeChunks(long filesize) {
#endif
} else {
#ifdef EXIV2_DEBUG_MESSAGES
std::cout << "Display Hex Dump [size:" << static_cast<unsigned long>(payload.size()) << "]" << std::endl;
std::cout << "Display Hex Dump [size:" << payload.size() << "]" << std::endl;
std::cout << binaryToHex(payload.c_data(), payload.size());
#endif
}
@ -807,14 +791,14 @@ void WebPImage::inject_VP8X(BasicIo& iIo, bool has_xmp, bool has_exif, bool has_
}
}
long WebPImage::getHeaderOffset(const byte* data, size_t data_size, const byte* header, size_t header_size) {
size_t WebPImage::getHeaderOffset(const byte* data, size_t data_size, const byte* header, size_t header_size) {
size_t pos = std::string::npos; // error value
if (data_size < header_size) {
return -1;
return pos;
}
long pos = -1;
for (size_t i = 0; i < data_size - header_size; i++) {
if (memcmp(header, &data[i], header_size) == 0) {
pos = static_cast<long>(i);
pos = i;
break;
}
}

Loading…
Cancel
Save