From ad4e13b8271908aad8efeaff29a1ea66ea3373e2 Mon Sep 17 00:00:00 2001 From: Kevin Backhouse Date: Tue, 21 Jun 2022 17:05:10 +0100 Subject: [PATCH] Change return type of BasicIo::tell() to size_t. --- include/exiv2/basicio.hpp | 14 ++++---- include/exiv2/bmffimage.hpp | 6 ++-- include/exiv2/webpimage.hpp | 11 ++++--- src/basicio.cpp | 14 ++++---- src/bmffimage.cpp | 60 ++++++++++++++++----------------- src/epsimage.cpp | 12 +++---- src/image.cpp | 10 +++--- src/jp2image.cpp | 27 +++++++-------- src/jpgimage.cpp | 10 +++--- src/pgfimage.cpp | 2 +- src/pngimage.cpp | 36 ++++++++++---------- src/psdimage.cpp | 6 ++-- src/tgaimage.cpp | 2 +- src/webpimage.cpp | 66 ++++++++++++++----------------------- 14 files changed, 129 insertions(+), 147 deletions(-) diff --git a/include/exiv2/basicio.hpp b/include/exiv2/basicio.hpp index 869a8044..756a0013 100644 --- a/include/exiv2/basicio.hpp +++ b/include/exiv2/basicio.hpp @@ -198,10 +198,9 @@ class EXIV2API BasicIo { //@{ /*! @brief Get the current IO position. - @return Offset from the start of IO if successful;
- -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;
@@ -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;
- -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;
@@ -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;
diff --git a/include/exiv2/bmffimage.hpp b/include/exiv2/bmffimage.hpp index cefa9212..d7963837 100644 --- a/include/exiv2/bmffimage.hpp +++ b/include/exiv2/bmffimage.hpp @@ -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 visits_; + std::set 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); diff --git a/include/exiv2/webpimage.hpp b/include/exiv2/webpimage.hpp index d9dda5a7..5fbc6d6b 100644 --- a/include/exiv2/webpimage.hpp +++ b/include/exiv2/webpimage.hpp @@ -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; diff --git a/src/basicio.cpp b/src/basicio.cpp index 6539b762..0a8c7191 100644 --- a/src/basicio.cpp +++ b/src/basicio.cpp @@ -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(pos); } size_t FileIo::size() const { @@ -786,8 +788,8 @@ int MemIo::munmap() { return 0; } -long MemIo::tell() const { - return static_cast(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(p_->idx_); +size_t RemoteIo::tell() const { + return p_->idx_; } size_t RemoteIo::size() const { diff --git a/src/bmffimage.cpp b/src/bmffimage.cpp index ce14fe5c..e27207d9 100644 --- a/src/bmffimage.cpp +++ b/src/bmffimage.cpp @@ -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(&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(pbox_end - restore), Exiv2::ErrorCode::kerCorruptedMetadata); + enforce(box_length - hdrsize <= pbox_end - restore, Exiv2::ErrorCode::kerCorruptedMetadata); - const auto buffer_size = static_cast(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(buffer_size); + return restore + buffer_size; } - DataBuf data(buffer_size); - const long box_end = restore + static_cast(data.size()); + DataBuf data(static_cast(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::max(), ErrorCode::kerCorruptedMetadata); - enforce(length <= std::numeric_limits::max(), ErrorCode::kerCorruptedMetadata); + enforce(start <= static_cast(std::numeric_limits::max()), ErrorCode::kerCorruptedMetadata); + enforce(length <= std::numeric_limits::max(), ErrorCode::kerCorruptedMetadata); // read and parse exif data - long restore = io_->tell(); + const size_t restore = io_->tell(); DataBuf exif(static_cast(length)); - io_->seek(static_cast(start), BasicIo::beg); + io_->seek(static_cast(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::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(i); + punt = i; } if (punt != eof) { - Internal::TiffParserWorker::decode(exifData(), iptcData(), xmpData(), exif.c_data(punt), - static_cast(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::max(), ErrorCode::kerCorruptedMetadata); + enforce(length - 8 <= std::numeric_limits::max(), ErrorCode::kerCorruptedMetadata); DataBuf data(static_cast(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(start), BasicIo::beg); + const size_t restore = io_->tell(); + io_->seek(static_cast(start), BasicIo::beg); auto lengthSizeT = static_cast(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::max() - static_cast(relative_position), - ErrorCode::kerCorruptedMetadata); + const size_t here = io_->tell(); + enforce(here <= std::numeric_limits::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(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(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(0), BasicIo::beg); + iIo.seek(0, BasicIo::beg); } return matched; } diff --git a/src/epsimage.cpp b/src/epsimage.cpp index 4c1d30d9..1d1c987d 100644 --- a/src/epsimage.cpp +++ b/src/epsimage.cpp @@ -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::max(), ErrorCode::kerImageWriteFailed); return static_cast(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); diff --git a/src/image.cpp b/src/image.cpp index 208fe9c2..93cbfa59 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -287,7 +287,7 @@ static bool typeValid(uint16_t type) { return type >= 1 && type <= 13; } -static std::set visits; // #547 +static std::set 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 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]; diff --git a/src/jp2image.cpp b/src/jp2image.cpp index 05298bda..5892557f 100644 --- a/src/jp2image.cpp +++ b/src/jp2image.cpp @@ -151,7 +151,7 @@ void Jp2Image::readMetadata() { while (io_->read(reinterpret_cast(&box), boxHSize) == boxHSize) { boxes_check(boxesCount++, boxem); - long position = io_->tell(); + const size_t position = io_->tell(); box.length = getLong(reinterpret_cast(&box.length), bigEndian); box.type = getLong(reinterpret_cast(&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(&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::max(); + size_t pos = (a == b && (a == 'I' || a == 'M')) ? 0 : notfound; // #1242 Forgive having Exif\0\0 in rawData.pData_ std::array 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(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(position - boxHSize + box.length), BasicIo::beg); + io_->seek(static_cast(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(&box), boxHSize) == boxHSize) { - long position = io_->tell(); + const size_t position = io_->tell(); box.length = getLong(reinterpret_cast(&box.length), bigEndian); box.type = getLong(reinterpret_cast(&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(&subBox), boxHSize) == boxHSize && - io_->tell() < position + static_cast(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(&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(position - boxHSize + box.length), BasicIo::beg); + io_->seek(static_cast(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(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(Jp2Signature.size()), BasicIo::cur); // Return to original position + iIo.seek(-static_cast(Jp2Signature.size()), BasicIo::cur); // Return to original position } return matched; } diff --git a/src/jpgimage.cpp b/src/jpgimage.cpp index da9c32b0..24d68a24 100644 --- a/src/jpgimage.cpp +++ b/src/jpgimage.cpp @@ -304,7 +304,7 @@ void JpegBase::printStructure(std::ostream& out, PrintStructureOption option, in } bool bPrint = option == kpsBasic || option == kpsRecursive; - std::vector iptcDataSegs; + std::vector 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::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(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 diff --git a/src/pgfimage.cpp b/src/pgfimage.cpp index c41c85b3..dcac5973 100644 --- a/src/pgfimage.cpp +++ b/src/pgfimage.cpp @@ -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::max() - 8, ErrorCode::kerCorruptedMetadata); - size_t size = headerSize + 8 - static_cast(io_->tell()); + size_t size = headerSize + 8 - io_->tell(); #ifdef EXIV2_DEBUG_MESSAGES std::cout << "Exiv2::PgfImage::readMetadata: Found Image data (" << size << " bytes)\n"; diff --git a/src/pngimage.cpp b/src/pngimage.cpp index a2415549..fe5b8c5e 100644 --- a/src/pngimage.cpp +++ b/src/pngimage.cpp @@ -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 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(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(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(dataOffset - name_l - 1), + enforce(dataOffset - name_l - 1 <= std::numeric_limits::max(), ErrorCode::kerCorruptedMetadata); + bGood = zlibToDataBuf(data.c_data(name_l + 1), static_cast(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(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(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(iccProfile_.size()), compressed)) { + enforce(iccProfile_.size() <= std::numeric_limits::max(), ErrorCode::kerCorruptedMetadata); + if (zlibToCompressed(iccProfile_.c_data(), static_cast(iccProfile_.size()), compressed)) { const auto nameLength = static_cast(profileName_.size()); const uint32_t chunkLength = nameLength + 2 + static_cast(compressed.size()); byte length[4]; diff --git a/src/psdimage.cpp b/src/psdimage.cpp index 94ac7788..b5e132e7 100644 --- a/src/psdimage.cpp +++ b/src/psdimage.cpp @@ -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) { diff --git a/src/tgaimage.cpp b/src/tgaimage.cpp index f48967f6..20d015f6 100644 --- a/src/tgaimage.cpp +++ b/src/tgaimage.cpp @@ -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; diff --git a/src/webpimage.cpp b/src/webpimage.cpp index dbdfde18..954254a2 100644 --- a/src/webpimage.cpp +++ b/src/webpimage.cpp @@ -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(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::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(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::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(io_->tell()) < filesize) { - auto offset = static_cast(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(size), - static_cast(offset)) + << Internal::stringFormat(" %s | %8u | %8u | ", chunkId.c_str(), size, static_cast(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(std::numeric_limits::max()), - Exiv2::ErrorCode::kerCorruptedMetadata); - - WebPImage::decodeChunks(static_cast(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(std::numeric_limits::max()), - Exiv2::ErrorCode::kerCorruptedMetadata); - const auto size = static_cast(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(&exifLongHeader), 4); + size_t pos = getHeaderOffset(payload.c_data(), payload.size(), reinterpret_cast(&exifLongHeader), 4); - if (pos == -1) { + if (pos == std::string::npos) { pos = getHeaderOffset(payload.c_data(), payload.size(), reinterpret_cast(&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(&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(&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(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(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(i); + pos = i; break; } }