From a357596a2e48e4dd2e0481b20de816ee319e5879 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= Date: Sun, 20 Feb 2022 09:20:13 +0100 Subject: [PATCH 01/19] Move params construction to the .cpp file --- app/exiv2.cpp | 27 +++++++++++++++++++++++++++ app/exiv2app.hpp | 44 ++------------------------------------------ 2 files changed, 29 insertions(+), 42 deletions(-) diff --git a/app/exiv2.cpp b/app/exiv2.cpp index 01f6c1c8..b45f859a 100644 --- a/app/exiv2.cpp +++ b/app/exiv2.cpp @@ -203,6 +203,33 @@ const Params::YodAdjust Params::emptyYodAdjust_[] = { { false, "-D", 0 }, }; +Params::Params() : optstring_(":hVvqfbuktTFa:Y:O:D:r:p:P:d:e:i:c:m:M:l:S:g:K:n:Q:"), + help_(false), + version_(false), + verbose_(false), + force_(false), + binary_(false), + unknown_(true), + preserve_(false), + timestamp_(false), + timestampOnly_(false), + fileExistsPolicy_(askPolicy), + adjust_(false), + printMode_(pmSummary), + printItems_(0), + printTags_(Exiv2::mdNone), + action_(0), + target_(ctExif|ctIptc|ctComment|ctXmp), + adjustment_(0), + format_("%Y%m%d_%H%M%S"), + formatSet_(false), + first_(true) +{ + yodAdjust_[yodYear] = emptyYodAdjust_[yodYear]; + yodAdjust_[yodMonth] = emptyYodAdjust_[yodMonth]; + yodAdjust_[yodDay] = emptyYodAdjust_[yodDay]; +} + Params& Params::instance() { if (nullptr == instance_) { diff --git a/app/exiv2app.hpp b/app/exiv2app.hpp index 680bb7f2..0b938623 100644 --- a/app/exiv2app.hpp +++ b/app/exiv2app.hpp @@ -35,21 +35,15 @@ #include "getopt.hpp" // + standard includes -#include #include #include #include #include -#ifdef EXV_HAVE_UNISTD_H -#include -#endif - // stdin handler includes #ifndef _MSC_VER #include #include -#include #if defined(__CYGWIN__) || defined(__MINGW__) #include #else @@ -57,12 +51,6 @@ #endif #endif -#if defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW__) || defined(_MSC_VER) -#include -#include -#endif - - // ***************************************************************************** // class definitions @@ -263,37 +251,9 @@ private: bool first_; + Params(); + private: - /*! - @brief Default constructor. Note that optstring_ is initialized here. - The c'tor is private to force instantiation through instance(). - */ - Params() : optstring_(":hVvqfbuktTFa:Y:O:D:r:p:P:d:e:i:c:m:M:l:S:g:K:n:Q:"), - help_(false), - version_(false), - verbose_(false), - force_(false), - binary_(false), - unknown_(true), - preserve_(false), - timestamp_(false), - timestampOnly_(false), - fileExistsPolicy_(askPolicy), - adjust_(false), - printMode_(pmSummary), - printItems_(0), - printTags_(Exiv2::mdNone), - action_(0), - target_(ctExif|ctIptc|ctComment|ctXmp), - adjustment_(0), - format_("%Y%m%d_%H%M%S"), - formatSet_(false), - first_(true) - { - yodAdjust_[yodYear] = emptyYodAdjust_[yodYear]; - yodAdjust_[yodMonth] = emptyYodAdjust_[yodMonth]; - yodAdjust_[yodDay] = emptyYodAdjust_[yodDay]; - } //! @name Helpers //@{ From 4163236e72e160c27f3288ba66252a4f3e62080b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= Date: Sun, 20 Feb 2022 09:22:55 +0100 Subject: [PATCH 02/19] Implement Params singleton in modern C++ way --- app/exiv2.cpp | 14 ++------------ app/exiv2app.hpp | 5 ----- 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/app/exiv2.cpp b/app/exiv2.cpp index b45f859a..d5da161b 100644 --- a/app/exiv2.cpp +++ b/app/exiv2.cpp @@ -181,7 +181,6 @@ int main(int argc, char* const argv[]) } taskFactory.cleanup(); - Params::cleanup(); Exiv2::XmpParser::terminate(); } } catch (const std::exception& exc) { @@ -195,7 +194,6 @@ int main(int argc, char* const argv[]) // ***************************************************************************** // class Params -Params* Params::instance_ = nullptr; const Params::YodAdjust Params::emptyYodAdjust_[] = { { false, "-Y", 0 }, @@ -232,16 +230,8 @@ Params::Params() : optstring_(":hVvqfbuktTFa:Y:O:D:r:p:P:d:e:i:c:m:M:l:S:g:K:n:Q Params& Params::instance() { - if (nullptr == instance_) { - instance_ = new Params; - } - return *instance_; -} - -void Params::cleanup() -{ - delete instance_; - instance_ = nullptr; + static Params instance_; + return instance_; } void Params::version(bool verbose, std::ostream& os) diff --git a/app/exiv2app.hpp b/app/exiv2app.hpp index 0b938623..5c04a4bc 100644 --- a/app/exiv2app.hpp +++ b/app/exiv2app.hpp @@ -148,9 +148,6 @@ public: //! Prevent copy-construction: not implemented. Params(const Params& rhs) = delete; - //! Destructor - static void cleanup(); - //! Enumerates print modes enum PrintMode { pmSummary, @@ -244,8 +241,6 @@ public: Exiv2::DataBuf stdinBuf; //!< DataBuf with the binary bytes from stdin private: - //! Pointer to the global Params object. - static Params* instance_; //! Initializer for year, month and day adjustment info. static const YodAdjust emptyYodAdjust_[]; From 67f574556ecca91f3dde3cd8e4ff322194246340 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= Date: Sun, 20 Feb 2022 09:49:01 +0100 Subject: [PATCH 03/19] Hide member variable --- app/exiv2.cpp | 11 +++++------ app/exiv2app.hpp | 3 --- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/app/exiv2.cpp b/app/exiv2.cpp index d5da161b..48bd1b82 100644 --- a/app/exiv2.cpp +++ b/app/exiv2.cpp @@ -47,6 +47,11 @@ // ***************************************************************************** // local declarations namespace { + const Params::YodAdjust emptyYodAdjust_[] = { + { false, "-Y", 0 }, + { false, "-O", 0 }, + { false, "-D", 0 }, + }; //! List of all command identifiers and corresponding strings const CmdIdAndString cmdIdAndString[] = { @@ -195,12 +200,6 @@ int main(int argc, char* const argv[]) // ***************************************************************************** // class Params -const Params::YodAdjust Params::emptyYodAdjust_[] = { - { false, "-Y", 0 }, - { false, "-O", 0 }, - { false, "-D", 0 }, -}; - Params::Params() : optstring_(":hVvqfbuktTFa:Y:O:D:r:p:P:d:e:i:c:m:M:l:S:g:K:n:Q:"), help_(false), version_(false), diff --git a/app/exiv2app.hpp b/app/exiv2app.hpp index 5c04a4bc..84099644 100644 --- a/app/exiv2app.hpp +++ b/app/exiv2app.hpp @@ -241,9 +241,6 @@ public: Exiv2::DataBuf stdinBuf; //!< DataBuf with the binary bytes from stdin private: - //! Initializer for year, month and day adjustment info. - static const YodAdjust emptyYodAdjust_[]; - bool first_; Params(); From 06ff936d06656e858dcd88f99f9abf5df205c131 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= Date: Sun, 20 Feb 2022 09:56:49 +0100 Subject: [PATCH 04/19] Replace dynamic array for std::vector --- app/exiv2.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/exiv2.cpp b/app/exiv2.cpp index 48bd1b82..a19f9298 100644 --- a/app/exiv2.cpp +++ b/app/exiv2.cpp @@ -1039,7 +1039,7 @@ using long_t = std::map; int Params::getopt(int argc, char* const Argv[]) { - auto argv = new char*[argc + 1]; + std::vector argv(argc+1); argv[argc] = nullptr; long_t longs; @@ -1084,7 +1084,7 @@ int Params::getopt(int argc, char* const Argv[]) } } - int rc = Util::Getopt::getopt(argc, argv, optstring_); + int rc = Util::Getopt::getopt(argc, argv.data(), optstring_); // Further consistency checks if (help_ || version_) { goto cleanup; @@ -1157,10 +1157,9 @@ int Params::getopt(int argc, char* const Argv[]) // cleanup the argument vector for (int i = 0; i < argc; i++) ::free(argv[i]); - delete [] argv; return rc; -} // Params::getopt +} // ***************************************************************************** // local implementations From b3517a6ab08155e5b3b8ca23155971744d6f3033 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= Date: Sun, 20 Feb 2022 10:01:23 +0100 Subject: [PATCH 05/19] Build hash table in place --- app/exiv2.cpp | 69 +++++++++++++++++++++++++-------------------------- 1 file changed, 34 insertions(+), 35 deletions(-) diff --git a/app/exiv2.cpp b/app/exiv2.cpp index a19f9298..da4b1119 100644 --- a/app/exiv2.cpp +++ b/app/exiv2.cpp @@ -1035,45 +1035,44 @@ void Params::getStdin(Exiv2::DataBuf& buf) } // Params::getStdin() -using long_t = std::map; - int Params::getopt(int argc, char* const Argv[]) { std::vector argv(argc+1); argv[argc] = nullptr; - long_t longs; - - longs["--adjust" ] = "-a"; - longs["--binary" ] = "-b"; - longs["--comment" ] = "-c"; - longs["--delete" ] = "-d"; - longs["--days" ] = "-D"; - longs["--extract" ] = "-e"; - longs["--force" ] = "-f"; - longs["--Force" ] = "-F"; - longs["--grep" ] = "-g"; - longs["--help" ] = "-h"; - longs["--insert" ] = "-i"; - longs["--keep" ] = "-k"; - longs["--key" ] = "-K"; - longs["--location" ] = "-l"; - longs["--modify" ] = "-m"; - longs["--Modify" ] = "-M"; - longs["--encode" ] = "-n"; - longs["--months" ] = "-O"; - longs["--print" ] = "-p"; - longs["--Print" ] = "-P"; - longs["--quiet" ] = "-q"; - longs["--log" ] = "-Q"; - longs["--rename" ] = "-r"; - longs["--suffix" ] = "-S"; - longs["--timestamp"] = "-t"; - longs["--Timestamp"] = "-T"; - longs["--unknown" ] = "-u"; - longs["--verbose" ] = "-v"; - longs["--Version" ] = "-V"; - longs["--version" ] = "-V"; - longs["--years" ] = "-Y"; + + std::unordered_map longs { + {"--adjust" , "-a"}, + {"--binary" , "-b"}, + {"--comment" , "-c"}, + {"--delete" , "-d"}, + {"--days" , "-D"}, + {"--extract" , "-e"}, + {"--force" , "-f"}, + {"--Force" , "-F"}, + {"--grep" , "-g"}, + {"--help" , "-h"}, + {"--insert" , "-i"}, + {"--keep" , "-k"}, + {"--key" , "-K"}, + {"--location" , "-l"}, + {"--modify" , "-m"}, + {"--Modify" , "-M"}, + {"--encode" , "-n"}, + {"--months" , "-O"}, + {"--print" , "-p"}, + {"--Print" , "-P"}, + {"--quiet" , "-q"}, + {"--log" , "-Q"}, + {"--rename" , "-r"}, + {"--suffix" , "-S"}, + {"--timestamp", "-t"}, + {"--Timestamp", "-T"}, + {"--unknown" , "-u"}, + {"--verbose" , "-v"}, + {"--Version" , "-V"}, + {"--version" , "-V"}, + {"--years" , "-Y"}, + }; for ( int i = 0 ; i < argc ; i++ ) { std::string arg(Argv[i]); From 2505e52345428dfafaffb72a2e14453ea871fccb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= Date: Sun, 20 Feb 2022 10:10:46 +0100 Subject: [PATCH 06/19] Avoid naked new operator in sample apps --- samples/addmoddel.cpp | 25 ++++++++++++++----------- samples/iotest.cpp | 13 +++++++------ samples/metacopy.cpp | 6 +++--- samples/tiff-test.cpp | 2 +- 4 files changed, 25 insertions(+), 21 deletions(-) diff --git a/samples/addmoddel.cpp b/samples/addmoddel.cpp index 56ed3e71..bc3648b3 100644 --- a/samples/addmoddel.cpp +++ b/samples/addmoddel.cpp @@ -57,7 +57,7 @@ try { std::cout << "Added a few tags the quick way.\n"; // Create a ASCII string value (note the use of create) - Exiv2::Value::UniquePtr v = Exiv2::Value::create(Exiv2::asciiString); + auto v = Exiv2::Value::create(Exiv2::asciiString); // Set the value to a string v->read("1999:12:31 23:59:59"); // Add the value together with its key to the Exif data container @@ -66,16 +66,16 @@ try { std::cout << "Added key \"" << key << "\", value \"" << *v << "\"\n"; // Now create a more interesting value (without using the create method) - Exiv2::URationalValue::UniquePtr rv(new Exiv2::URationalValue); + Exiv2::URationalValue rv; // Set two rational components from a string - rv->read("1/2 1/3"); + rv.read("1/2 1/3"); // Add more elements through the extended interface of rational value - rv->value_.emplace_back(2, 3); - rv->value_.emplace_back(3, 4); + rv.value_.emplace_back(2, 3); + rv.value_.emplace_back(3, 4); // Add the key and value pair to the Exif data key = Exiv2::ExifKey("Exif.Image.PrimaryChromaticities"); - exifData.add(key, rv.get()); - std::cout << "Added key \"" << key << "\", value \"" << *rv << "\"\n"; + exifData.add(key, &rv); + std::cout << "Added key \"" << key << "\", value \"" << rv << "\"\n"; // ************************************************************************* // Modify Exif data @@ -92,18 +92,21 @@ try { // Alternatively, we can use findKey() key = Exiv2::ExifKey("Exif.Image.PrimaryChromaticities"); auto pos = exifData.findKey(key); - if (pos == exifData.end()) throw Exiv2::Error(Exiv2::kerErrorMessage, "Key not found"); + if (pos == exifData.end()) + throw Exiv2::Error(Exiv2::kerErrorMessage, "Key not found"); + // Get a pointer to a copy of the value v = pos->getValue(); // Downcast the Value pointer to its actual type auto prv = dynamic_cast(v.release()); if (prv == nullptr) throw Exiv2::Error(Exiv2::kerErrorMessage, "Downcast failed"); - rv = Exiv2::URationalValue::UniquePtr(prv); + + rv = Exiv2::URationalValue(*prv); // Modify the value directly through the interface of URationalValue - rv->value_.at(2) = {88, 77}; + rv.value_.at(2) = {88, 77}; // Copy the modified value back to the metadatum - pos->setValue(rv.get()); + pos->setValue(&rv); std::cout << "Modified key \"" << key << "\", new value \"" << pos->value() << "\"\n"; diff --git a/samples/iotest.cpp b/samples/iotest.cpp index 3e379e6f..620ce76f 100644 --- a/samples/iotest.cpp +++ b/samples/iotest.cpp @@ -65,8 +65,10 @@ int main(int argc, char* const argv[]) if ( argc >= 5 ) { int blocksize = argc==6 ? atoi(ba) : 10000; // ensure blocksize is sane - if (blocksize>1024*1024) blocksize=10000; - Exiv2::byte* bytes = blocksize > 0 ? new Exiv2::byte[blocksize] : nullptr; + if (blocksize>1024*1024) + blocksize=10000; + + std::vector bytes (blocksize); // copy fileIn from a remote location. BasicIo::UniquePtr io = Exiv2::ImageFactory::createIo(fr); @@ -78,11 +80,11 @@ int main(int argc, char* const argv[]) Error(Exiv2::kerFileOpenFailed, output.path() , "w+b", strError()); } size_t l = 0; - if ( bytes ) { + if ( !bytes.empty() ) { int r ; - while ( (r=io->read(bytes,blocksize)) > 0 ) { + while ( (r=io->read(bytes.data(),blocksize)) > 0 ) { l += r; - output.write(bytes,r) ; + output.write(bytes.data(),r) ; } } else { // read/write byte-wise (#1029) @@ -90,7 +92,6 @@ int main(int argc, char* const argv[]) output.putb(io->getb()) ; } } - delete[] bytes; output.close(); } diff --git a/samples/metacopy.cpp b/samples/metacopy.cpp index fa00b0d7..a43b20f5 100644 --- a/samples/metacopy.cpp +++ b/samples/metacopy.cpp @@ -49,9 +49,9 @@ try { } // Use MemIo to increase test coverage. - Exiv2::BasicIo::UniquePtr fileIo(new Exiv2::FileIo(params.read_)); - Exiv2::BasicIo::UniquePtr memIo(new Exiv2::MemIo); - memIo->transfer(*fileIo); + Exiv2::FileIo fileIo(params.read_); + auto memIo = std::make_unique(); + memIo->transfer(fileIo); Exiv2::Image::UniquePtr readImg = Exiv2::ImageFactory::open(std::move(memIo)); assert(readImg.get() != 0); diff --git a/samples/tiff-test.cpp b/samples/tiff-test.cpp index 6174d92b..dd5e92b5 100644 --- a/samples/tiff-test.cpp +++ b/samples/tiff-test.cpp @@ -91,7 +91,7 @@ void mini1(const char* path) void mini9(const char* path) { - TiffImage tiffImage(BasicIo::UniquePtr(new FileIo(path)), false); + TiffImage tiffImage(std::make_unique(path), false); tiffImage.readMetadata(); std::cout << "MIME type: " << tiffImage.mimeType() << "\n"; From aec36f86d7cacbaf4a36266613a9b1b57eb9684a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= Date: Sun, 20 Feb 2022 11:09:30 +0100 Subject: [PATCH 07/19] Replace naked new operators --- include/exiv2/basicio.hpp | 2 +- src/basicio.cpp | 32 ++++++++++++++++---------------- src/cr2image.cpp | 4 ++-- src/crwimage_int.cpp | 23 +++++++++++------------ src/crwimage_int.hpp | 4 ++-- src/exif.cpp | 8 ++++---- src/jpgimage.cpp | 5 ++--- src/orfimage.cpp | 4 ++-- src/properties.cpp | 7 ++++--- src/tags.cpp | 8 ++++---- src/tiffimage.cpp | 4 ++-- src/tiffimage_int.cpp | 2 +- 12 files changed, 51 insertions(+), 52 deletions(-) diff --git a/include/exiv2/basicio.hpp b/include/exiv2/basicio.hpp index c456344d..d6952b09 100644 --- a/include/exiv2/basicio.hpp +++ b/include/exiv2/basicio.hpp @@ -916,7 +916,7 @@ namespace Exiv2 { // Pimpl idiom class Impl; //! Pointer to implementation - Impl* p_ {nullptr}; + std::unique_ptr p_; }; // class RemoteIo /*! diff --git a/src/basicio.cpp b/src/basicio.cpp index 807d75c8..d1627a16 100644 --- a/src/basicio.cpp +++ b/src/basicio.cpp @@ -219,7 +219,7 @@ namespace Exiv2 { } // FileIo::Impl::stat FileIo::FileIo(const std::string& path) - : p_(new Impl(path)) + : p_(std::make_unique(path)) { } @@ -548,9 +548,11 @@ namespace Exiv2 { int FileIo::close() { int rc = 0; - if (munmap() != 0) rc = 2; + if (munmap() != 0) + rc = 2; if (p_->fp_ != nullptr) { - if (std::fclose(p_->fp_) != 0) rc |= 1; + if (std::fclose(p_->fp_) != 0) + rc |= 1; p_->fp_ = nullptr; } return rc; @@ -738,12 +740,12 @@ namespace Exiv2 { } MemIo::MemIo() - : p_(new Impl()) + : p_(std::make_unique()) { } MemIo::MemIo(const byte* data, long size) - : p_(new Impl(data, size)) + : p_(std::make_unique(data, size)) { } @@ -1172,7 +1174,6 @@ namespace Exiv2 { { if (p_) { close(); - delete p_; } } @@ -1588,11 +1589,10 @@ namespace Exiv2 { // encode base64 size_t encodeLength = ((size + 2) / 3) * 4 + 1; - auto encodeData = new char[encodeLength]; - base64encode(data, size, encodeData, encodeLength); + std::vector encodeData (encodeLength); + base64encode(data, size, encodeData.data(), encodeLength); // url encode - const std::string urlencodeData = urlencode(encodeData); - delete[] encodeData; + const std::string urlencodeData = urlencode(encodeData.data()); std::stringstream ss; ss << "path=" << hostInfo_.Path << "&" @@ -1613,9 +1613,10 @@ namespace Exiv2 { throw Error(kerFileOpenFailed, "http",Exiv2::Internal::stringFormat("%d",serverCode), hostInfo_.Path); } } + HttpIo::HttpIo(const std::string& url, size_t blockSize) { - p_ = new HttpImpl(url, blockSize); + p_ = std::make_unique(url, blockSize); } #ifdef EXV_USE_CURL @@ -1776,11 +1777,10 @@ namespace Exiv2 { // encode base64 size_t encodeLength = ((size + 2) / 3) * 4 + 1; - auto encodeData = new char[encodeLength]; - base64encode(data, size, encodeData, encodeLength); + std::vector encodeData (encodeLength); + base64encode(data, size, encodeData.data(), encodeLength); // url encode - const std::string urlencodeData = urlencode(encodeData); - delete[] encodeData; + const std::string urlencodeData = urlencode(encodeData.data()); std::stringstream ss; ss << "path=" << hostInfo.Path << "&" << "from=" << from << "&" @@ -1824,7 +1824,7 @@ namespace Exiv2 { CurlIo::CurlIo(const std::string& url, size_t blockSize) { - p_ = new CurlImpl(url, blockSize); + p_ = std::make_unique(url, blockSize); } #endif diff --git a/src/cr2image.cpp b/src/cr2image.cpp index cbbcecbe..f2e99f17 100644 --- a/src/cr2image.cpp +++ b/src/cr2image.cpp @@ -177,7 +177,7 @@ namespace Exiv2 { ed.erase(std::remove_if(ed.begin(), ed.end(), FindExifdatum(filteredIfd)), ed.end()); } - std::unique_ptr header(new Cr2Header(byteOrder)); + Cr2Header header(byteOrder); OffsetWriter offsetWriter; offsetWriter.setOrigin(OffsetWriter::cr2RawIfdOffset, Cr2Header::offset2addr(), byteOrder); return TiffParserWorker::encode(io, @@ -188,7 +188,7 @@ namespace Exiv2 { xmpData, Tag::root, TiffMapping::findEncoder, - header.get(), + &header, &offsetWriter); } diff --git a/src/crwimage_int.cpp b/src/crwimage_int.cpp index c869b325..76f71242 100644 --- a/src/crwimage_int.cpp +++ b/src/crwimage_int.cpp @@ -169,8 +169,6 @@ namespace Exiv2 { CiffHeader::~CiffHeader() { - delete pRootDir_; - delete[] pPadding_; } CiffDirectory::~CiffDirectory() @@ -214,12 +212,12 @@ namespace Exiv2 { throw Error(kerNotACrwImage); } - delete[] pPadding_; - pPadding_ = new byte[offset_ - 14]; + pPadding_.clear(); + pPadding_.resize(offset_ - 14); padded_ = offset_ - 14; - std::memcpy(pPadding_, pData + 14, padded_); + std::copy_n(pData+14, padded_, pPadding_.begin()); - pRootDir_ = new CiffDirectory; + pRootDir_ = std::make_unique(); pRootDir_->readDirectory(pData + offset_, size - offset_, byteOrder_); } // CiffHeader::read @@ -329,8 +327,9 @@ namespace Exiv2 { void CiffHeader::decode(Image& image) const { // Nothing to decode from the header itself, just add correct byte order - if (pRootDir_) pRootDir_->decode(image, byteOrder_); - } // CiffHeader::decode + if (pRootDir_) + pRootDir_->decode(image, byteOrder_); + } void CiffComponent::decode(Image& image, ByteOrder byteOrder) const { @@ -369,9 +368,9 @@ namespace Exiv2 { append(blob, reinterpret_cast(signature_), 8); o += 8; // Pad as needed - if (pPadding_) { + if (pPadding_.empty() == false) { assert(padded_ == offset_ - o); - append(blob, pPadding_, padded_); + append(blob, pPadding_.data(), padded_); } else { for (uint32_t i = o; i < offset_; ++i) { @@ -622,7 +621,7 @@ namespace Exiv2 { assert(rootDirectory == 0x0000); crwDirs.pop(); if (!pRootDir_) { - pRootDir_ = new CiffDirectory; + pRootDir_ = std::make_unique(); } CiffComponent* child = pRootDir_->add(crwDirs, crwTagId); if (child) { @@ -683,7 +682,7 @@ namespace Exiv2 { } if (cc_ == nullptr) { // Tag doesn't exist yet, add it - m_ = UniquePtr(new CiffEntry(crwTagId, tag())); + m_ = std::make_unique(crwTagId, tag()); cc_ = m_.get(); add(std::move(m_)); } diff --git a/src/crwimage_int.hpp b/src/crwimage_int.hpp index 935802f6..0c0c3bfd 100644 --- a/src/crwimage_int.hpp +++ b/src/crwimage_int.hpp @@ -493,10 +493,10 @@ namespace Exiv2 { // DATA static const char signature_[]; //!< Canon CRW signature "HEAPCCDR" - CiffDirectory* pRootDir_ = nullptr; //!< Pointer to the root directory + std::unique_ptr pRootDir_; //!< Pointer to the root directory ByteOrder byteOrder_ = littleEndian; //!< Applicable byte order uint32_t offset_ = 0; //!< Offset to the start of the root dir - byte* pPadding_ = nullptr; //!< Pointer to the (unknown) remainder + std::vector pPadding_; //!< the (unknown) remainder uint32_t padded_ = 0; //!< Number of padding-bytes }; // class CiffHeader diff --git a/src/exif.cpp b/src/exif.cpp index a8054000..64d14134 100644 --- a/src/exif.cpp +++ b/src/exif.cpp @@ -181,7 +181,7 @@ namespace Exiv2 { template Exiv2::Exifdatum& setValue(Exiv2::Exifdatum& exifDatum, const T& value) { - auto v = std::unique_ptr >(new Exiv2::ValueType); + auto v = std::make_unique>(); v->value_.push_back(value); exifDatum.value_ = std::move(v); return exifDatum; @@ -696,9 +696,9 @@ namespace Exiv2 { // Encode and check if the result fits into a JPEG Exif APP1 segment MemIo mio1; - std::unique_ptr header(new TiffHeader(byteOrder, 0x00000008, false)); + TiffHeader header(byteOrder, 0x00000008, false); WriteMethod wm = TiffParserWorker::encode(mio1, pData, size, ed, emptyIptc, emptyXmp, Tag::root, - TiffMapping::findEncoder, header.get(), nullptr); + TiffMapping::findEncoder, &header, nullptr); if (mio1.size() <= 65527) { append(blob, mio1.mmap(), static_cast(mio1.size())); return wm; @@ -796,7 +796,7 @@ namespace Exiv2 { // Encode the remaining Exif tags again, don't care if it fits this time MemIo mio2; wm = TiffParserWorker::encode(mio2, pData, size, ed, emptyIptc, emptyXmp, Tag::root, TiffMapping::findEncoder, - header.get(), nullptr); + &header, nullptr); append(blob, mio2.mmap(), static_cast(mio2.size())); #ifdef EXIV2_DEBUG_MESSAGES if (wm == wmIntrusive) { diff --git a/src/jpgimage.cpp b/src/jpgimage.cpp index 9f55ada0..2c7b47ee 100644 --- a/src/jpgimage.cpp +++ b/src/jpgimage.cpp @@ -848,13 +848,12 @@ namespace Exiv2 { throw Error(kerDataSourceOpenFailed, io_->path(), strError()); } IoCloser closer(*io_); - BasicIo::UniquePtr tempIo(new MemIo); - assert (tempIo.get() != 0); + auto tempIo = std::make_unique(); doWriteMetadata(*tempIo); // may throw io_->close(); io_->transfer(*tempIo); // may throw - } // JpegBase::writeMetadata + } void JpegBase::doWriteMetadata(BasicIo& outIo) { diff --git a/src/orfimage.cpp b/src/orfimage.cpp index 645bb9aa..d5dae40c 100644 --- a/src/orfimage.cpp +++ b/src/orfimage.cpp @@ -183,9 +183,9 @@ namespace Exiv2 { ed.erase(std::remove_if(ed.begin(), ed.end(), FindExifdatum(filteredIfd)), ed.end()); } - std::unique_ptr header(new OrfHeader(byteOrder)); + OrfHeader header(byteOrder); return TiffParserWorker::encode(io, pData, size, ed, iptcData, xmpData, Tag::root, TiffMapping::findEncoder, - header.get(), nullptr); + &header, nullptr); } // ************************************************************************* diff --git a/src/properties.cpp b/src/properties.cpp index 31ed9c39..73caedbd 100644 --- a/src/properties.cpp +++ b/src/properties.cpp @@ -4186,19 +4186,20 @@ namespace Exiv2 { prefix_ = prefix; } - XmpKey::XmpKey(const std::string& key) : p_(new Impl) + XmpKey::XmpKey(const std::string& key) : p_(std::make_unique()) { p_->decomposeKey(key); } - XmpKey::XmpKey(const std::string& prefix, const std::string& property) : p_(new Impl(prefix, property)) + XmpKey::XmpKey(const std::string& prefix, const std::string& property) + : p_(std::make_unique(prefix, property)) { } XmpKey::~XmpKey() = default; XmpKey::XmpKey(const XmpKey& rhs) - : p_(new Impl(*rhs.p_)) + : p_(std::make_unique(*rhs.p_)) { } diff --git a/src/tags.cpp b/src/tags.cpp index d2b3dace..f63c4099 100644 --- a/src/tags.cpp +++ b/src/tags.cpp @@ -295,7 +295,7 @@ namespace Exiv2 { } ExifKey::ExifKey(uint16_t tag, const std::string& groupName) - : p_(new Impl) + : p_(std::make_unique()) { IfdId ifdId = groupId(groupName); // Todo: Test if this condition can be removed @@ -311,7 +311,7 @@ namespace Exiv2 { } ExifKey::ExifKey(const TagInfo& ti) - : p_(new Impl) + : p_(std::make_unique()) { auto ifdId = static_cast(ti.ifdId_); if (!Internal::isExifIfd(ifdId) && !Internal::isMakerIfd(ifdId)) { @@ -322,13 +322,13 @@ namespace Exiv2 { } ExifKey::ExifKey(const std::string& key) - : p_(new Impl) + : p_(std::make_unique()) { p_->decomposeKey(key); } ExifKey::ExifKey(const ExifKey& rhs) - : p_(new Impl(*rhs.p_)) + : p_(std::make_unique(*rhs.p_)) { } diff --git a/src/tiffimage.cpp b/src/tiffimage.cpp index e693c715..4353b5b3 100644 --- a/src/tiffimage.cpp +++ b/src/tiffimage.cpp @@ -298,9 +298,9 @@ namespace Exiv2 { ed.erase(std::remove_if(ed.begin(), ed.end(), FindExifdatum(filteredIfd)), ed.end()); } - std::unique_ptr header(new TiffHeader(byteOrder)); + TiffHeader header(byteOrder); return TiffParserWorker::encode(io, pData, size, ed, iptcData, xmpData, Tag::root, TiffMapping::findEncoder, - header.get(), nullptr); + &header, nullptr); } // TiffParser::encode // ************************************************************************* diff --git a/src/tiffimage_int.cpp b/src/tiffimage_int.cpp index 80aabf1e..e0eabf89 100644 --- a/src/tiffimage_int.cpp +++ b/src/tiffimage_int.cpp @@ -2057,7 +2057,7 @@ namespace Exiv2 { // Create standard TIFF header if necessary std::unique_ptr ph; if (!pHeader) { - ph = std::unique_ptr(new TiffHeader); + ph = std::make_unique(); pHeader = ph.get(); } From f1e04ee86685c2f0bbe69e7dd3ede3ede83ed66a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= Date: Sun, 20 Feb 2022 12:42:00 +0100 Subject: [PATCH 08/19] Replace DataBuf internal buffer with std::vector --- app/actions.cpp | 12 +++++-- app/exiv2.cpp | 5 ++- include/exiv2/basicio.hpp | 1 + include/exiv2/types.hpp | 2 +- src/basicio.cpp | 2 ++ src/jpgimage.cpp | 5 ++- src/pngchunk_int.cpp | 6 ++-- src/types.cpp | 44 +++++++++++++------------ tests/bugfixes/github/test_issue_428.py | 3 ++ 9 files changed, 48 insertions(+), 32 deletions(-) diff --git a/app/actions.cpp b/app/actions.cpp index 09d7dca9..4b418fac 100644 --- a/app/actions.cpp +++ b/app/actions.cpp @@ -62,6 +62,8 @@ #ifdef _MSC_VER # include #include +#include +#include #else # include #endif @@ -1820,11 +1822,15 @@ namespace { bool bStdout = tgt == "-"; Exiv2::DataBuf stdIn; - if ( bStdin ) + Exiv2::Image::UniquePtr sourceImage; + if ( bStdin ) { Params::instance().getStdin(stdIn); + auto ioStdin = std::make_unique(stdIn.c_data(),stdIn.size()); + sourceImage = Exiv2::ImageFactory::open(std::move(ioStdin)); + } else { + sourceImage = Exiv2::ImageFactory::open(source); + } - auto ioStdin = std::make_unique(stdIn.c_data(),stdIn.size()); - auto sourceImage = bStdin ? Exiv2::ImageFactory::open(std::move(ioStdin)) : Exiv2::ImageFactory::open(source); assert(sourceImage); sourceImage->readMetadata(); diff --git a/app/exiv2.cpp b/app/exiv2.cpp index da4b1119..6b1162dd 100644 --- a/app/exiv2.cpp +++ b/app/exiv2.cpp @@ -37,11 +37,14 @@ #include #include #include - #include #if defined(_MSC_VER) #include +#include +#include +#else +#include #endif // ***************************************************************************** diff --git a/include/exiv2/basicio.hpp b/include/exiv2/basicio.hpp index d6952b09..cdd2ec42 100644 --- a/include/exiv2/basicio.hpp +++ b/include/exiv2/basicio.hpp @@ -764,6 +764,7 @@ namespace Exiv2 { class EXIV2API RemoteIo : public BasicIo { public: //! Destructor. Releases all managed memory. + RemoteIo(); ~RemoteIo() override; //@} diff --git a/include/exiv2/types.hpp b/include/exiv2/types.hpp index c3182f66..b8b5a813 100644 --- a/include/exiv2/types.hpp +++ b/include/exiv2/types.hpp @@ -247,7 +247,7 @@ namespace Exiv2 { private: // DATA //! Pointer to the buffer, 0 if none has been allocated - byte* pData_; + std::vector pData_; //! The current size of the buffer long size_; }; // class DataBuf diff --git a/src/basicio.cpp b/src/basicio.cpp index d1627a16..6b1ed0fc 100644 --- a/src/basicio.cpp +++ b/src/basicio.cpp @@ -1170,6 +1170,8 @@ namespace Exiv2 { delete[] blocksMap_; } + RemoteIo::RemoteIo() = default; + RemoteIo::~RemoteIo() { if (p_) { diff --git a/src/jpgimage.cpp b/src/jpgimage.cpp index 2c7b47ee..85e46fff 100644 --- a/src/jpgimage.cpp +++ b/src/jpgimage.cpp @@ -369,17 +369,16 @@ namespace Exiv2 { while (marker != sos_ && marker != eoi_ && search > 0) { // 2-byte buffer for reading the size. byte sizebuf[2]; - uint16_t size = 0; + uint16_t size = 0; // Size of the segment, including the 2-byte size field if (markerHasLength(marker)) { io_->readOrThrow(sizebuf, 2, kerFailedToReadImageData); size = getUShort(sizebuf, bigEndian); - // `size` is the size of the segment, including the 2-byte size field - // that we just read. enforce(size >= 2, kerFailedToReadImageData); } // Read the rest of the segment. DataBuf buf(size); + /// \todo check if it makes sense to check for size if (size > 0) { io_->readOrThrow(buf.data(2), size - 2, kerFailedToReadImageData); buf.copyBytes(0, sizebuf, 2); diff --git a/src/pngchunk_int.cpp b/src/pngchunk_int.cpp index 33a013e6..9e89cbc8 100644 --- a/src/pngchunk_int.cpp +++ b/src/pngchunk_int.cpp @@ -154,7 +154,7 @@ namespace Exiv2 arr = DataBuf(text, textsize); } else if (type == iTXt_Chunk) { enforce(data.size() >= Safe::add(keysize, 3), Exiv2::kerCorruptedMetadata); - const size_t nullCount = std::count(data.c_data(keysize + 3), data.c_data(data.size()), '\0'); + const size_t nullCount = std::count(data.c_data(keysize + 3), data.c_data(data.size()-1), '\0'); enforce(nullCount >= nullSeparators, Exiv2::kerCorruptedMetadata); // Extract a deflate compressed or uncompressed UTF-8 text chunk @@ -277,7 +277,7 @@ namespace Exiv2 uint32_t sizeIptc = 0; uint32_t sizeHdr = 0; - const byte* pEnd = psData.c_data(psData.size()); + const byte* pEnd = psData.c_data(psData.size()-1); const byte* pCur = psData.c_data(); while (pCur < pEnd && 0 == Photoshop::locateIptcIrb(pCur, static_cast(pEnd - pCur), &record, &sizeHdr, &sizeIptc)) { @@ -551,7 +551,7 @@ namespace Exiv2 } const char* sp = text.c_str(1); // current byte (space pointer) - const char* eot = text.c_str(text.size()); // end of text + const char* eot = text.c_str(text.size()-1); // end of text if (sp >= eot) { return DataBuf(); diff --git a/src/types.cpp b/src/types.cpp index ac59f9c0..a804bef5 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -119,39 +119,38 @@ namespace Exiv2 { } DataBuf::DataBuf(DataBuf&& rhs) - : pData_(rhs.pData_), size_(rhs.size_) + : pData_(std::move(rhs.pData_)), size_(rhs.size_) { - rhs.pData_ = nullptr; rhs.size_ = 0; } DataBuf::~DataBuf() - { delete[] pData_; } + { } - DataBuf::DataBuf() : pData_(nullptr), size_(0) + DataBuf::DataBuf() : pData_(), size_(0) {} - DataBuf::DataBuf(long size) : pData_(new byte[size]()), size_(size) + DataBuf::DataBuf(long size) : pData_(size), size_(size) {} - DataBuf::DataBuf(const byte* pData, long size) : pData_(nullptr), size_(0) + DataBuf::DataBuf(const byte* pData, long size) : pData_(), size_(0) { if (size > 0) { - pData_ = new byte[size]; - std::memcpy(pData_, pData, size); + pData_.resize(size); + std::memcpy(pData_.data(), pData, size); size_ = size; } } DataBuf::DataBuf(const DataBuf& rhs) - : DataBuf(rhs.pData_, rhs.size_) + : DataBuf(rhs.pData_.data(), rhs.size_) {} DataBuf& DataBuf::operator=(DataBuf&& rhs) { - if (this == &rhs) return *this; - reset(); - std::swap(pData_, rhs.pData_); + if (this == &rhs) + return *this; + pData_ = std::move(rhs.pData_); std::swap(size_, rhs.size_); return *this; } @@ -159,8 +158,7 @@ namespace Exiv2 { void DataBuf::alloc(long size) { if (size > size_) { - delete[] pData_; - pData_ = new byte[size]; + pData_.resize(size); size_ = size; } } @@ -168,11 +166,10 @@ namespace Exiv2 { void DataBuf::resize(long size) { if (size > size_) { - byte* newbuf = new byte[size]; + std::vector newbuf(size); if (size_ > 0) { - memcpy(newbuf, pData_, size_); + memcpy(newbuf.data(), pData_.data(), size_); } - delete[] pData_; pData_ = newbuf; } size_ = size; @@ -180,13 +177,12 @@ namespace Exiv2 { void DataBuf::reset() { - delete[] pData_; - pData_ = nullptr; + pData_.clear(); size_ = 0; } void DataBuf::clear() { - memset(pData_, 0, size_); + memset(pData_.data(), 0, size_); } uint8_t Exiv2::DataBuf::read_uint8(size_t offset) const { @@ -245,11 +241,13 @@ namespace Exiv2 { ull2Data(&pData_[offset], x, byteOrder); } + /// \todo do not use void* void Exiv2::DataBuf::copyBytes(size_t offset, const void* buf, size_t bufsize) { if (static_cast(size_) < bufsize || offset > size_ - bufsize) { throw std::overflow_error("Overflow in Exiv2::DataBuf::copyBytes"); + } if (bufsize > 0) { + memcpy(&pData_[offset], buf, bufsize); } - memcpy(&pData_[offset], buf, bufsize); } int Exiv2::DataBuf::cmpBytes(size_t offset, const void* buf, size_t bufsize) const { @@ -262,6 +260,8 @@ namespace Exiv2 { byte* Exiv2::DataBuf::data(size_t offset) { if (static_cast(size_) < offset) { throw std::overflow_error("Overflow in Exiv2::DataBuf::c_data"); + } else if (size_ == 0 || static_cast(size_) == offset) { + return nullptr; } return &pData_[offset]; } @@ -269,6 +269,8 @@ namespace Exiv2 { const byte* Exiv2::DataBuf::c_data(size_t offset) const { if (static_cast(size_) < offset) { throw std::overflow_error("Overflow in Exiv2::DataBuf::c_data"); + } else if (size_ == 0 || static_cast(size_) == offset) { + return nullptr; } return &pData_[offset]; } diff --git a/tests/bugfixes/github/test_issue_428.py b/tests/bugfixes/github/test_issue_428.py index 9e875621..e05086f9 100644 --- a/tests/bugfixes/github/test_issue_428.py +++ b/tests/bugfixes/github/test_issue_428.py @@ -26,12 +26,15 @@ class PngReadRawProfile(metaclass=system_tests.CaseMeta): commands = ["$exiv2 " + fname for fname in filenames] stdout = [""] * len(filenames) stderr = [ stderr_exception(fname) for fname in filenames[0:5] ] + stderr.append("""$exiv2_exception_message """ + filenames[5] + """: $kerInputDataReadFailed """) + stderr.append("""Error: XMP Toolkit error 201: Error in XMLValidator Warning: Failed to decode XMP metadata. """ + stderr_exception(filenames[6])) + stderr.append("""Warning: Failed to decode Exif metadata. """ + stderr_exception(filenames[7])) From 6e5071472625ed6ffbb71c531212c01ef91d93ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= Date: Wed, 23 Feb 2022 22:02:37 +0100 Subject: [PATCH 09/19] Replace c style arrays by std::array --- src/jpgimage.cpp | 57 ++++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/src/jpgimage.cpp b/src/jpgimage.cpp index 85e46fff..d1fed0c7 100644 --- a/src/jpgimage.cpp +++ b/src/jpgimage.cpp @@ -256,16 +256,17 @@ namespace Exiv2 { // Write new iptc record if we have it DataBuf rawIptc = IptcParser::encode(iptcData); if (rawIptc.size() > 0) { - byte tmpBuf[12]; - std::memcpy(tmpBuf, Photoshop::irbId_[0], 4); - us2Data(tmpBuf + 4, iptc_, bigEndian); + std::array tmpBuf; + std::memcpy(tmpBuf.data(), Photoshop::irbId_[0], 4); + us2Data(tmpBuf.data() + 4, iptc_, bigEndian); tmpBuf[6] = 0; tmpBuf[7] = 0; - ul2Data(tmpBuf + 8, rawIptc.size(), bigEndian); - append(psBlob, tmpBuf, 12); + ul2Data(tmpBuf.data() + 8, rawIptc.size(), bigEndian); + append(psBlob, tmpBuf.data(), 12); append(psBlob, rawIptc.c_data(), rawIptc.size()); // Data is padded to be even (but not included in size) - if (rawIptc.size() & 1) psBlob.push_back(0x00); + if (rawIptc.size() & 1) + psBlob.push_back(0x00); } // Write existing stuff after record, // skip the current and all remaining IPTC blocks @@ -1049,16 +1050,16 @@ namespace Exiv2 { exifSize = blob.size(); } if (exifSize > 0) { - byte tmpBuf[10]; + std::array tmpBuf; // Write APP1 marker, size of APP1 field, Exif id and Exif data tmpBuf[0] = 0xff; tmpBuf[1] = app1_; if (exifSize > 0xffff - 8) throw Error(kerTooLargeJpegSegment, "Exif"); - us2Data(tmpBuf + 2, static_cast(exifSize + 8), bigEndian); - std::memcpy(tmpBuf + 4, exifId_, 6); - if (outIo.write(tmpBuf, 10) != 10) + us2Data(tmpBuf.data() + 2, static_cast(exifSize + 8), bigEndian); + std::memcpy(tmpBuf.data() + 4, exifId_, 6); + if (outIo.write(tmpBuf.data(), 10) != 10) throw Error(kerImageWriteFailed); // Write new Exif data buffer @@ -1078,16 +1079,16 @@ namespace Exiv2 { } } if (!xmpPacket_.empty()) { - byte tmpBuf[33]; + std::array tmpBuf; // Write APP1 marker, size of APP1 field, XMP id and XMP packet tmpBuf[0] = 0xff; tmpBuf[1] = app1_; if (xmpPacket_.size() > 0xffff - 31) throw Error(kerTooLargeJpegSegment, "XMP"); - us2Data(tmpBuf + 2, static_cast(xmpPacket_.size() + 31), bigEndian); - std::memcpy(tmpBuf + 4, xmpId_, 29); - if (outIo.write(tmpBuf, 33) != 33) + us2Data(tmpBuf.data() + 2, static_cast(xmpPacket_.size() + 31), bigEndian); + std::memcpy(tmpBuf.data() + 4, xmpId_, 29); + if (outIo.write(tmpBuf.data(), 33) != 33) throw Error(kerImageWriteFailed); // Write new XMP packet @@ -1100,7 +1101,7 @@ namespace Exiv2 { } if (iccProfileDefined()) { - byte tmpBuf[4]; + std::array tmpBuf; // Write APP2 marker, size of APP2 field, and IccProfile // See comments in readMetadata() about the ICC embedding specification tmpBuf[0] = 0xff; @@ -1118,11 +1119,11 @@ namespace Exiv2 { size -= bytes; // write JPEG marker (2 bytes) - if (outIo.write(tmpBuf, 2) != 2) + if (outIo.write(tmpBuf.data(), 2) != 2) throw Error(kerImageWriteFailed); // JPEG Marker // write length (2 bytes). length includes the 2 bytes for the length - us2Data(tmpBuf + 2, static_cast(2 + 14 + bytes), bigEndian); - if (outIo.write(tmpBuf + 2, 2) != 2) + us2Data(tmpBuf.data() + 2, static_cast(2 + 14 + bytes), bigEndian); + if (outIo.write(tmpBuf.data() + 2, 2) != 2) throw Error(kerImageWriteFailed); // JPEG Length // write the ICC_PROFILE header (14 bytes) @@ -1146,7 +1147,7 @@ namespace Exiv2 { static_cast(psBlob.size()), iptcData_); const long maxChunkSize = 0xffff - 16; const byte* chunkStart = newPsData.c_data(); - const byte* chunkEnd = newPsData.c_data(newPsData.size()); + const byte* chunkEnd = newPsData.c_data(newPsData.size()-1); while (chunkStart < chunkEnd) { // Determine size of next chunk long chunkSize = static_cast(chunkEnd - chunkStart); @@ -1162,12 +1163,12 @@ namespace Exiv2 { } // Write APP13 marker, chunk size, and ps3Id - byte tmpBuf[18]; + std::array tmpBuf; tmpBuf[0] = 0xff; tmpBuf[1] = app13_; - us2Data(tmpBuf + 2, static_cast(chunkSize + 16), bigEndian); - std::memcpy(tmpBuf + 4, Photoshop::ps3Id_, 14); - if (outIo.write(tmpBuf, 18) != 18) + us2Data(tmpBuf.data() + 2, static_cast(chunkSize + 16), bigEndian); + std::memcpy(tmpBuf.data() + 4, Photoshop::ps3Id_, 14); + if (outIo.write(tmpBuf.data(), 18) != 18) throw Error(kerImageWriteFailed); if (outIo.error()) throw Error(kerImageWriteFailed); @@ -1185,16 +1186,16 @@ namespace Exiv2 { } if (comPos == count) { if (!comment_.empty()) { - byte tmpBuf[4]; + std::array tmpBuf; // Write COM marker, size of comment, and string tmpBuf[0] = 0xff; tmpBuf[1] = com_; if (comment_.length() > 0xffff - 3) throw Error(kerTooLargeJpegSegment, "JPEG comment"); - us2Data(tmpBuf + 2, static_cast(comment_.length() + 3), bigEndian); + us2Data(tmpBuf.data() + 2, static_cast(comment_.length() + 3), bigEndian); - if (outIo.write(tmpBuf, 4) != 4) + if (outIo.write(tmpBuf.data(), 4) != 4) throw Error(kerImageWriteFailed); if (outIo.write(reinterpret_cast(const_cast(comment_.data())), static_cast(comment_.length())) != static_cast(comment_.length())) @@ -1215,11 +1216,11 @@ namespace Exiv2 { std::find(skipApp2Icc.begin(), skipApp2Icc.end(), count) != skipApp2Icc.end() || skipCom == count) { --search; } else { - byte tmpBuf[2]; + std::array tmpBuf; // Write marker and a copy of the segment. tmpBuf[0] = 0xff; tmpBuf[1] = marker; - if (outIo.write(tmpBuf, 2) != 2) + if (outIo.write(tmpBuf.data(), 2) != 2) throw Error(kerImageWriteFailed); if (outIo.write(buf.c_data(), size) != size) throw Error(kerImageWriteFailed); From 615ccff5abe14536847973d1160e31a75477b8ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= Date: Wed, 23 Feb 2022 22:25:52 +0100 Subject: [PATCH 10/19] Fix another case revealed by tests --- samples/metacopy.cpp | 4 +++- src/iptc.cpp | 1 + src/jpgimage.cpp | 5 +++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/samples/metacopy.cpp b/samples/metacopy.cpp index a43b20f5..5c931dda 100644 --- a/samples/metacopy.cpp +++ b/samples/metacopy.cpp @@ -59,7 +59,9 @@ try { Exiv2::Image::UniquePtr writeImg = Exiv2::ImageFactory::open(params.write_); assert(writeImg.get() != 0); - if (params.preserve_) writeImg->readMetadata(); + if (params.preserve_) { + writeImg->readMetadata(); + } if (params.iptc_) { writeImg->setIptcData(readImg->iptcData()); } diff --git a/src/iptc.cpp b/src/iptc.cpp index 776ef9ca..b3874a46 100644 --- a/src/iptc.cpp +++ b/src/iptc.cpp @@ -505,6 +505,7 @@ namespace Exiv2 { DataBuf IptcParser::encode(const IptcData& iptcData) { + /// \todo if iptcData.size() == 0 return early DataBuf buf(iptcData.size()); byte *pWrite = buf.data(); diff --git a/src/jpgimage.cpp b/src/jpgimage.cpp index d1fed0c7..eaf186e2 100644 --- a/src/jpgimage.cpp +++ b/src/jpgimage.cpp @@ -1013,6 +1013,7 @@ namespace Exiv2 { // potential to change segment ordering (which is allowed). // Segments are erased if there is no assigned metadata. while (marker != sos_ && search > 0) { + /// \todo same block than above ... reuse!!! // 2-byte buffer for reading the size. byte sizebuf[2]; uint16_t size = 0; @@ -1147,10 +1148,10 @@ namespace Exiv2 { static_cast(psBlob.size()), iptcData_); const long maxChunkSize = 0xffff - 16; const byte* chunkStart = newPsData.c_data(); - const byte* chunkEnd = newPsData.c_data(newPsData.size()-1); + const byte* chunkEnd = newPsData.size() == 0 ? nullptr : newPsData.c_data(newPsData.size()-1); while (chunkStart < chunkEnd) { // Determine size of next chunk - long chunkSize = static_cast(chunkEnd - chunkStart); + long chunkSize = static_cast(chunkEnd + 1 - chunkStart); if (chunkSize > maxChunkSize) { chunkSize = maxChunkSize; // Don't break at a valid IRB boundary From 2bacff0f5c002ddae2fde132c1b182be9a7613bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= Date: Wed, 23 Feb 2022 22:38:46 +0100 Subject: [PATCH 11/19] Simplify DataBuf --- include/exiv2/types.hpp | 8 ++---- src/types.cpp | 63 +++++++++++++++-------------------------- 2 files changed, 25 insertions(+), 46 deletions(-) diff --git a/include/exiv2/types.hpp b/include/exiv2/types.hpp index b8b5a813..69edf8c1 100644 --- a/include/exiv2/types.hpp +++ b/include/exiv2/types.hpp @@ -215,7 +215,7 @@ namespace Exiv2 { //! Fill the buffer with zeros. void clear(); - long size() const { return size_; } + long size() const { return pData_.size(); } uint8_t read_uint8(size_t offset) const; void write_uint8(size_t offset, uint8_t x); @@ -245,12 +245,8 @@ namespace Exiv2 { const char* c_str(size_t offset = 0) const; private: - // DATA - //! Pointer to the buffer, 0 if none has been allocated std::vector pData_; - //! The current size of the buffer - long size_; - }; // class DataBuf + }; /*! * @brief Create a new Slice from a DataBuf given the bounds. diff --git a/src/types.cpp b/src/types.cpp index a804bef5..5ea2714c 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -119,31 +119,26 @@ namespace Exiv2 { } DataBuf::DataBuf(DataBuf&& rhs) - : pData_(std::move(rhs.pData_)), size_(rhs.size_) + : pData_(std::move(rhs.pData_)) { - rhs.size_ = 0; } DataBuf::~DataBuf() { } - DataBuf::DataBuf() : pData_(), size_(0) + DataBuf::DataBuf() : pData_() {} - DataBuf::DataBuf(long size) : pData_(size), size_(size) + DataBuf::DataBuf(long size) : pData_(size) {} - DataBuf::DataBuf(const byte* pData, long size) : pData_(), size_(0) + DataBuf::DataBuf(const byte* pData, long size) : pData_(size) { - if (size > 0) { - pData_.resize(size); - std::memcpy(pData_.data(), pData, size); - size_ = size; - } + std::copy_n(pData, size, pData_.begin()); } DataBuf::DataBuf(const DataBuf& rhs) - : DataBuf(rhs.pData_.data(), rhs.size_) + : DataBuf(rhs.pData_.data(), rhs.pData_.size()) {} DataBuf& DataBuf::operator=(DataBuf&& rhs) @@ -151,91 +146,79 @@ namespace Exiv2 { if (this == &rhs) return *this; pData_ = std::move(rhs.pData_); - std::swap(size_, rhs.size_); return *this; } void DataBuf::alloc(long size) { - if (size > size_) { - pData_.resize(size); - size_ = size; - } + pData_.resize(size); } void DataBuf::resize(long size) { - if (size > size_) { - std::vector newbuf(size); - if (size_ > 0) { - memcpy(newbuf.data(), pData_.data(), size_); - } - pData_ = newbuf; - } - size_ = size; + pData_.resize(size); } void DataBuf::reset() { pData_.clear(); - size_ = 0; } void DataBuf::clear() { - memset(pData_.data(), 0, size_); + std::fill(pData_.begin(), pData_.end(), 0); } uint8_t Exiv2::DataBuf::read_uint8(size_t offset) const { - if (offset >= static_cast(size_)) { + if (offset >= pData_.size()) { throw std::overflow_error("Overflow in Exiv2::DataBuf::read_uint8"); } return pData_[offset]; } void Exiv2::DataBuf::write_uint8(size_t offset, uint8_t x) { - if (offset >= static_cast(size_)) { + if (offset >= pData_.size()) { throw std::overflow_error("Overflow in Exiv2::DataBuf::write_uint8"); } pData_[offset] = x; } uint16_t Exiv2::DataBuf::read_uint16(size_t offset, ByteOrder byteOrder) const { - if (size_ < 2 || offset > static_cast(size_ - 2)) { + if (pData_.size() < 2 || offset > (pData_.size() - 2)) { throw std::overflow_error("Overflow in Exiv2::DataBuf::read_uint16"); } return getUShort(&pData_[offset], byteOrder); } void Exiv2::DataBuf::write_uint16(size_t offset, uint16_t x, ByteOrder byteOrder) { - if (size_ < 2 || offset > static_cast(size_ - 2)) { + if (pData_.size() < 2 || offset > (pData_.size() - 2)) { throw std::overflow_error("Overflow in Exiv2::DataBuf::write_uint16"); } us2Data(&pData_[offset], x, byteOrder); } uint32_t Exiv2::DataBuf::read_uint32(size_t offset, ByteOrder byteOrder) const { - if (size_ < 4 || offset > static_cast(size_ - 4)) { + if (pData_.size() < 4 || offset > (pData_.size() - 4)) { throw std::overflow_error("Overflow in Exiv2::DataBuf::read_uint32"); } return getULong(&pData_[offset], byteOrder); } void Exiv2::DataBuf::write_uint32(size_t offset, uint32_t x, ByteOrder byteOrder) { - if (size_ < 4 || offset > static_cast(size_ - 4)) { + if (pData_.size() < 4 || offset > (pData_.size() - 4)) { throw std::overflow_error("Overflow in Exiv2::DataBuf::write_uint32"); } ul2Data(&pData_[offset], x, byteOrder); } uint64_t Exiv2::DataBuf::read_uint64(size_t offset, ByteOrder byteOrder) const { - if (size_ < 8 || offset > static_cast(size_ - 8)) { + if (pData_.size() < 8 || offset > (pData_.size() - 8)) { throw std::overflow_error("Overflow in Exiv2::DataBuf::read_uint64"); } return getULongLong(&pData_[offset], byteOrder); } void Exiv2::DataBuf::write_uint64(size_t offset, uint64_t x, ByteOrder byteOrder) { - if (size_ < 8 || offset > static_cast(size_ - 8)) { + if (pData_.size() < 8 || offset > (pData_.size() - 8)) { throw std::overflow_error("Overflow in Exiv2::DataBuf::write_uint64"); } ull2Data(&pData_[offset], x, byteOrder); @@ -243,7 +226,7 @@ namespace Exiv2 { /// \todo do not use void* void Exiv2::DataBuf::copyBytes(size_t offset, const void* buf, size_t bufsize) { - if (static_cast(size_) < bufsize || offset > size_ - bufsize) { + if (pData_.size() < bufsize || offset > pData_.size() - bufsize) { throw std::overflow_error("Overflow in Exiv2::DataBuf::copyBytes"); } if (bufsize > 0) { memcpy(&pData_[offset], buf, bufsize); @@ -251,25 +234,25 @@ namespace Exiv2 { } int Exiv2::DataBuf::cmpBytes(size_t offset, const void* buf, size_t bufsize) const { - if (static_cast(size_) < bufsize || offset > size_ - bufsize) { + if (pData_.size() < bufsize || offset > pData_.size() - bufsize) { throw std::overflow_error("Overflow in Exiv2::DataBuf::cmpBytes"); } return memcmp(&pData_[offset], buf, bufsize); } byte* Exiv2::DataBuf::data(size_t offset) { - if (static_cast(size_) < offset) { + if (pData_.size() < offset) { throw std::overflow_error("Overflow in Exiv2::DataBuf::c_data"); - } else if (size_ == 0 || static_cast(size_) == offset) { + } else if (pData_.size() == 0 || pData_.size() == offset) { return nullptr; } return &pData_[offset]; } const byte* Exiv2::DataBuf::c_data(size_t offset) const { - if (static_cast(size_) < offset) { + if (pData_.size() < offset) { throw std::overflow_error("Overflow in Exiv2::DataBuf::c_data"); - } else if (size_ == 0 || static_cast(size_) == offset) { + } else if (pData_.size() == 0 || pData_.size() == offset) { return nullptr; } return &pData_[offset]; From 3a749e6861da426b932e7e3d24de531bc32aec8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= Date: Wed, 23 Feb 2022 22:44:42 +0100 Subject: [PATCH 12/19] No need to define copy & move ctors --- include/exiv2/types.hpp | 24 +----------------------- src/types.cpp | 23 ----------------------- 2 files changed, 1 insertion(+), 46 deletions(-) diff --git a/include/exiv2/types.hpp b/include/exiv2/types.hpp index 69edf8c1..b88c8f74 100644 --- a/include/exiv2/types.hpp +++ b/include/exiv2/types.hpp @@ -166,37 +166,15 @@ namespace Exiv2 { //! @name Creators //@{ //! Default constructor - DataBuf(); + DataBuf() = default; //! Constructor with an initial buffer size explicit DataBuf(long size); //! Constructor, copies an existing buffer DataBuf(const byte* pData, long size); - /*! - @brief Copy constructor. Copies an existing DataBuf. - */ - DataBuf(const DataBuf& rhs); - /*! - @brief Move constructor. Transfers the buffer to the newly created - object similar to std::unique_ptr, i.e., the original object is - modified. - */ - DataBuf(DataBuf&& rhs); - //! Destructor, deletes the allocated buffer - ~DataBuf(); //@} //! @name Manipulators //@{ - /*! - @brief Assignment operator. Transfers the buffer and releases the - buffer at the original object similar to std::unique_ptr, i.e., - the original object is modified. - */ - DataBuf& operator=(DataBuf&& rhs); - - // No copy assignment. - DataBuf& operator=(const DataBuf&) = delete; - /*! @brief Allocate a data buffer of at least the given size. Note that if the requested \em size is less than the current buffer size, no diff --git a/src/types.cpp b/src/types.cpp index 5ea2714c..9db1db5a 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -118,17 +118,6 @@ namespace Exiv2 { return tit->size_; } - DataBuf::DataBuf(DataBuf&& rhs) - : pData_(std::move(rhs.pData_)) - { - } - - DataBuf::~DataBuf() - { } - - DataBuf::DataBuf() : pData_() - {} - DataBuf::DataBuf(long size) : pData_(size) {} @@ -137,18 +126,6 @@ namespace Exiv2 { std::copy_n(pData, size, pData_.begin()); } - DataBuf::DataBuf(const DataBuf& rhs) - : DataBuf(rhs.pData_.data(), rhs.pData_.size()) - {} - - DataBuf& DataBuf::operator=(DataBuf&& rhs) - { - if (this == &rhs) - return *this; - pData_ = std::move(rhs.pData_); - return *this; - } - void DataBuf::alloc(long size) { pData_.resize(size); From 5d627433fcd98865ae514b1da06e245935e85fc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= Date: Wed, 23 Feb 2022 22:49:58 +0100 Subject: [PATCH 13/19] Remove useless DataBuf::clear() --- include/exiv2/types.hpp | 3 --- src/crwimage_int.cpp | 5 ----- src/image.cpp | 1 - src/jp2image.cpp | 2 -- src/pgfimage.cpp | 1 - src/pngimage.cpp | 4 ---- src/tiffcomposite_int.cpp | 2 -- src/tiffvisitor_int.cpp | 1 - src/types.cpp | 5 ----- unitTests/test_types.cpp | 1 - 10 files changed, 25 deletions(-) diff --git a/include/exiv2/types.hpp b/include/exiv2/types.hpp index b88c8f74..78c19196 100644 --- a/include/exiv2/types.hpp +++ b/include/exiv2/types.hpp @@ -190,9 +190,6 @@ namespace Exiv2 { void reset(); //@} - //! Fill the buffer with zeros. - void clear(); - long size() const { return pData_.size(); } uint8_t read_uint8(size_t offset) const; diff --git a/src/crwimage_int.cpp b/src/crwimage_int.cpp index 76f71242..6cb86baf 100644 --- a/src/crwimage_int.cpp +++ b/src/crwimage_int.cpp @@ -1019,7 +1019,6 @@ namespace Exiv2 { auto size = static_cast(comment.size()); if (cc && cc->size() > size) size = cc->size(); DataBuf buf(size); - buf.clear(); buf.copyBytes(0, comment.data(), comment.size()); pHead->add(pCrwMapping->crwTagId_, pCrwMapping->crwDir_, std::move(buf)); } @@ -1027,7 +1026,6 @@ namespace Exiv2 { if (cc) { // Just delete the value, do not remove the tag DataBuf buf(cc->size()); - buf.clear(); cc->setValue(std::move(buf)); } } @@ -1117,7 +1115,6 @@ namespace Exiv2 { } if (t != 0) { DataBuf buf(12); - buf.clear(); buf.write_uint32(0, static_cast(t), pHead->byteOrder()); pHead->add(pCrwMapping->crwTagId_, pCrwMapping->crwDir_, std::move(buf)); } @@ -1152,7 +1149,6 @@ namespace Exiv2 { size = cc->size(); } DataBuf buf(size); - buf.clear(); if (cc) buf.copyBytes(8, cc->pData() + 8, cc->size() - 8); if (edX != edEnd && edX->size() == 4) { edX->copy(buf.data(), pHead->byteOrder()); @@ -1197,7 +1193,6 @@ namespace Exiv2 { { const uint16_t size = 1024; DataBuf buf(size); - buf.clear(); uint16_t len = 0; diff --git a/src/image.cpp b/src/image.cpp index 945747ad..c7022951 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -406,7 +406,6 @@ namespace Exiv2 { enforce(allocate64 <= static_cast(std::numeric_limits::max()), kerCorruptedMetadata); const long allocate = static_cast(allocate64); DataBuf buf(allocate); // allocate a buffer - buf.clear(); buf.copyBytes(0, dir.c_data(8), 4); // copy dir[8:11] into buffer (short strings) // We have already checked that this multiplication cannot overflow. diff --git a/src/jp2image.cpp b/src/jp2image.cpp index 078e3a4d..1778f634 100644 --- a/src/jp2image.cpp +++ b/src/jp2image.cpp @@ -766,8 +766,6 @@ static void boxes_check(size_t b,size_t m) #endif // Read chunk header. - - bheaderBuf.clear(); long bufRead = io_->read(bheaderBuf.data(), bheaderBuf.size()); if (io_->error()) throw Error(kerFailedToReadImageData); if (bufRead != bheaderBuf.size()) throw Error(kerInputDataReadFailed); diff --git a/src/pgfimage.cpp b/src/pgfimage.cpp index e21f0817..d6e3ae82 100644 --- a/src/pgfimage.cpp +++ b/src/pgfimage.cpp @@ -138,7 +138,6 @@ namespace Exiv2 { if (size == 0) return; DataBuf imgData(size); - imgData.clear(); long bufRead = io_->read(imgData.data(), imgData.size()); if (io_->error()) throw Error(kerFailedToReadImageData); if (bufRead != imgData.size()) throw Error(kerInputDataReadFailed); diff --git a/src/pngimage.cpp b/src/pngimage.cpp index 90ece7cf..6c567084 100644 --- a/src/pngimage.cpp +++ b/src/pngimage.cpp @@ -246,7 +246,6 @@ namespace Exiv2 { while( !io_->eof() && ::strcmp(chType,"IEND") ) { size_t address = io_->tell(); - cheaderBuf.clear(); long bufRead = io_->read(cheaderBuf.data(), cheaderBuf.size()); if (io_->error()) throw Error(kerFailedToReadImageData); if (bufRead != cheaderBuf.size()) throw Error(kerInputDataReadFailed); @@ -440,7 +439,6 @@ namespace Exiv2 { while(!io_->eof()) { - cheaderBuf.clear(); readChunk(cheaderBuf, *io_); // Read chunk header. // Decode chunk data length. @@ -560,8 +558,6 @@ namespace Exiv2 { while(!io_->eof()) { // Read chunk header. - - cheaderBuf.clear(); long bufRead = io_->read(cheaderBuf.data(), 8); if (io_->error()) throw Error(kerFailedToReadImageData); if (bufRead != 8) throw Error(kerInputDataReadFailed); diff --git a/src/tiffcomposite_int.cpp b/src/tiffcomposite_int.cpp index a2ce2ef3..983900fa 100644 --- a/src/tiffcomposite_int.cpp +++ b/src/tiffcomposite_int.cpp @@ -1294,7 +1294,6 @@ namespace Exiv2 { << ": Writing offset " << o2 << "\n"; #endif DataBuf buf(static_cast(strips_.size()) * 4); - buf.clear(); uint32_t idx = 0; for (auto&& strip : strips_) { idx += writeOffset(buf.data(idx), o2, tiffType(), byteOrder); @@ -1905,7 +1904,6 @@ namespace { { if (curr < tobe) { Exiv2::DataBuf buf(tobe - curr); - buf.clear(); ioWrapper.write(buf.c_data(), buf.size()); return tobe - curr; } diff --git a/src/tiffvisitor_int.cpp b/src/tiffvisitor_int.cpp index 8ea7b31a..575afe99 100644 --- a/src/tiffvisitor_int.cpp +++ b/src/tiffvisitor_int.cpp @@ -624,7 +624,6 @@ namespace Exiv2 { if (rawIptc.size() % 4 != 0) { // Pad the last unsignedLong value with 0s buf.alloc((rawIptc.size() / 4) * 4 + 4); - buf.clear(); buf.copyBytes(0, rawIptc.c_data(), rawIptc.size()); } else { diff --git a/src/types.cpp b/src/types.cpp index 9db1db5a..7cc19277 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -141,10 +141,6 @@ namespace Exiv2 { pData_.clear(); } - void DataBuf::clear() { - std::fill(pData_.begin(), pData_.end(), 0); - } - uint8_t Exiv2::DataBuf::read_uint8(size_t offset) const { if (offset >= pData_.size()) { throw std::overflow_error("Overflow in Exiv2::DataBuf::read_uint8"); @@ -201,7 +197,6 @@ namespace Exiv2 { ull2Data(&pData_[offset], x, byteOrder); } - /// \todo do not use void* void Exiv2::DataBuf::copyBytes(size_t offset, const void* buf, size_t bufsize) { if (pData_.size() < bufsize || offset > pData_.size() - bufsize) { throw std::overflow_error("Overflow in Exiv2::DataBuf::copyBytes"); diff --git a/unitTests/test_types.cpp b/unitTests/test_types.cpp index 96c5742c..2d050209 100644 --- a/unitTests/test_types.cpp +++ b/unitTests/test_types.cpp @@ -62,7 +62,6 @@ TEST(DataBuf, allocatesDataWithNonEmptyConstructor) TEST(DataBuf, read_write_endianess) { DataBuf buf(4 + 1 + 2 + 4 + 8); - buf.clear(); // Big endian. buf.write_uint8(4, 0x01); From 7dea0050b136fa2662abac35bad17fdff840bd3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= Date: Thu, 24 Feb 2022 20:34:13 +0100 Subject: [PATCH 14/19] Factor out duplicated piece of code --- include/exiv2/jpgimage.hpp | 2 + src/jpgimage.cpp | 84 +++++++++++++++----------------------- 2 files changed, 36 insertions(+), 50 deletions(-) diff --git a/include/exiv2/jpgimage.hpp b/include/exiv2/jpgimage.hpp index 9d038a9a..46c14867 100644 --- a/include/exiv2/jpgimage.hpp +++ b/include/exiv2/jpgimage.hpp @@ -279,6 +279,8 @@ namespace Exiv2 { byte advanceToMarker(ErrorCode err) const; //@} + DataBuf readNextSegment(byte marker); + /*! @brief Is the marker followed by a non-zero payload? @param marker The marker at the start of a segment diff --git a/src/jpgimage.cpp b/src/jpgimage.cpp index eaf186e2..72c2531b 100644 --- a/src/jpgimage.cpp +++ b/src/jpgimage.cpp @@ -855,6 +855,29 @@ namespace Exiv2 { io_->transfer(*tempIo); // may throw } + DataBuf JpegBase::readNextSegment(byte marker) + { + // 2-byte buffer for reading the size. + byte sizebuf[2]; + uint16_t size = 0; + if (markerHasLength(marker)) { + io_->readOrThrow(sizebuf, 2, kerFailedToReadImageData); + size = getUShort(sizebuf, bigEndian); + // `size` is the size of the segment, including the 2-byte size field + // that we just read. + enforce(size >= 2, kerFailedToReadImageData); + } + + // Read the rest of the segment. + DataBuf buf(size); + if (size > 0) { + assert(size >= 2); // enforced above + io_->readOrThrow(buf.data(2), size - 2, kerFailedToReadImageData); + buf.copyBytes(0, sizebuf, 2); + } + return buf; + } + void JpegBase::doWriteMetadata(BasicIo& outIo) { if (!io_->isopen()) @@ -899,47 +922,28 @@ namespace Exiv2 { // to insert after it. But if app0 comes after com, app1 and app13 then // don't bother. while (marker != sos_ && marker != eoi_ && search < 6) { - // 2-byte buffer for reading the size. - byte sizebuf[2]; - uint16_t size = 0; - if (markerHasLength(marker)) { - io_->readOrThrow(sizebuf, 2, kerFailedToReadImageData); - size = getUShort(sizebuf, bigEndian); - // `size` is the size of the segment, including the 2-byte size field - // that we just read. - enforce(size >= 2, kerFailedToReadImageData); - } - - // Read the rest of the segment. - DataBuf buf(size); - if (size > 0) { - assert(size >= 2); // enforced above - io_->readOrThrow(buf.data(2), size - 2, kerFailedToReadImageData); - buf.copyBytes(0, sizebuf, 2); - } + DataBuf buf = readNextSegment(marker); if (marker == app0_) { - assert(markerHasLength(marker)); - assert(size >= 2); // Because this marker has a length field. insertPos = count + 1; } else if (skipApp1Exif == notfound && marker == app1_ && - size >= 8 && // prevent out-of-bounds read in memcmp on next line + buf.size() >= 8 && // prevent out-of-bounds read in memcmp on next line buf.cmpBytes(2, exifId_, 6) == 0) { skipApp1Exif = count; ++search; - if (size > 8) { - rawExif.alloc(size - 8); - rawExif.copyBytes(0, buf.c_data(8), size - 8); + if (buf.size() > 8) { + rawExif.alloc(buf.size() - 8); + rawExif.copyBytes(0, buf.c_data(8), buf.size() - 8); } } else if (skipApp1Xmp == notfound && marker == app1_ && - size >= 31 && // prevent out-of-bounds read in memcmp on next line + buf.size() >= 31 && // prevent out-of-bounds read in memcmp on next line buf.cmpBytes(2, xmpId_, 29) == 0) { skipApp1Xmp = count; ++search; } else if (marker == app2_ && - size >= 13 && // prevent out-of-bounds read in memcmp on next line + buf.size() >= 13 && // prevent out-of-bounds read in memcmp on next line buf.cmpBytes(2, iccId_, 11) == 0) { skipApp2Icc.push_back(count); if (!foundIccData) { @@ -948,21 +952,19 @@ namespace Exiv2 { } } else if (!foundCompletePsData && marker == app13_ && - size >= 16 && // prevent out-of-bounds read in memcmp on next line + buf.size() >= 16 && // prevent out-of-bounds read in memcmp on next line buf.cmpBytes(2, Photoshop::ps3Id_, 14) == 0) { #ifdef EXIV2_DEBUG_MESSAGES std::cerr << "Found APP13 Photoshop PS3 segment\n"; #endif skipApp13Ps3.push_back(count); // Append to psBlob - append(psBlob, buf.c_data(16), size - 16); + append(psBlob, buf.c_data(16), buf.size() - 16); // Check whether psBlob is complete if (!psBlob.empty() && Photoshop::valid(&psBlob[0], static_cast(psBlob.size()))) { foundCompletePsData = true; } } else if (marker == com_ && skipCom == notfound) { - assert(markerHasLength(marker)); - assert(size >= 2); // Because this marker has a length field. // Jpegs can have multiple comments, but for now only handle // the first one (most jpegs only have one anyway). skipCom = count; @@ -1013,25 +1015,7 @@ namespace Exiv2 { // potential to change segment ordering (which is allowed). // Segments are erased if there is no assigned metadata. while (marker != sos_ && search > 0) { - /// \todo same block than above ... reuse!!! - // 2-byte buffer for reading the size. - byte sizebuf[2]; - uint16_t size = 0; - if (markerHasLength(marker)) { - io_->readOrThrow(sizebuf, 2, kerFailedToReadImageData); - size = getUShort(sizebuf, bigEndian); - // `size` is the size of the segment, including the 2-byte size field - // that we just read. - enforce(size >= 2, kerFailedToReadImageData); - } - - // Read the rest of the segment. - DataBuf buf(size); - if (size > 0) { - assert(size >= 2); // enforced above - io_->readOrThrow(buf.data(2), size - 2, kerFailedToReadImageData); - buf.copyBytes(0, sizebuf, 2); - } + DataBuf buf = readNextSegment(marker); if (insertPos == count) { // Write Exif data first so that - if there is no app0 - we @@ -1223,7 +1207,7 @@ namespace Exiv2 { tmpBuf[1] = marker; if (outIo.write(tmpBuf.data(), 2) != 2) throw Error(kerImageWriteFailed); - if (outIo.write(buf.c_data(), size) != size) + if (outIo.write(buf.c_data(), buf.size()) != buf.size()) throw Error(kerImageWriteFailed); if (outIo.error()) throw Error(kerImageWriteFailed); From b9f9d041eabc0cd9620ca4373190f167085a9b44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= Date: Thu, 24 Feb 2022 22:39:44 +0100 Subject: [PATCH 15/19] Several transformations on DataBuf + migration to size_t - Provide begin/end iterators to DataBuf and simplify code - Adapt test output after last changes - Replacing long by size_t in value.hpp - Use size_t in some Photoshop functions - Remove some static_casts --- app/actions.cpp | 40 ++- app/exiv2.cpp | 8 +- include/exiv2/basicio.hpp | 45 ++- include/exiv2/bmffimage.hpp | 10 +- include/exiv2/exif.hpp | 38 +-- include/exiv2/image.hpp | 6 +- include/exiv2/iptc.hpp | 16 +- include/exiv2/jpgimage.hpp | 27 +- include/exiv2/metadatum.hpp | 2 +- include/exiv2/preview.hpp | 4 +- include/exiv2/tiffimage.hpp | 2 +- include/exiv2/types.hpp | 22 +- include/exiv2/value.hpp | 286 ++++++++----------- include/exiv2/xmp_exiv2.hpp | 2 +- samples/addmoddel.cpp | 2 +- samples/iotest.cpp | 10 +- samples/largeiptc-test.cpp | 2 +- samples/tiff-test.cpp | 2 +- samples/xmpparser-test.cpp | 2 +- src/basicio.cpp | 143 +++++----- src/bmffimage.cpp | 64 ++--- src/casiomn_int.cpp | 18 +- src/convert.cpp | 36 +-- src/crwimage.cpp | 6 +- src/crwimage_int.cpp | 4 +- src/epsimage.cpp | 13 +- src/exif.cpp | 66 ++--- src/image.cpp | 10 +- src/iptc.cpp | 10 +- src/jp2image.cpp | 72 ++--- src/jpgimage.cpp | 100 +++---- src/makernote_int.cpp | 17 +- src/mrwimage.cpp | 2 +- src/olympusmn_int.cpp | 4 +- src/panasonicmn_int.cpp | 7 +- src/pgfimage.cpp | 40 ++- src/pngchunk_int.cpp | 96 +++---- src/pngchunk_int.hpp | 10 +- src/pngimage.cpp | 93 +++--- src/preview.cpp | 93 +++--- src/psdimage.cpp | 164 +++++++---- src/rafimage.cpp | 50 ++-- src/tags_int.cpp | 4 +- src/tags_int.hpp | 2 +- src/tiffcomposite_int.cpp | 140 ++++----- src/tiffcomposite_int.hpp | 38 +-- src/tiffimage.cpp | 11 +- src/tiffimage_int.cpp | 16 +- src/tiffvisitor_int.cpp | 30 +- src/types.cpp | 23 +- src/value.cpp | 120 ++++---- src/webpimage.cpp | 33 +-- src/xmp.cpp | 6 +- src/xmpsidecar.cpp | 13 +- tests/bugfixes/github/test_CVE_2018_12265.py | 3 +- tests/bugfixes/github/test_issue_428.py | 9 +- unitTests/test_basicio.cpp | 26 +- unitTests/test_futils.cpp | 20 +- 58 files changed, 1066 insertions(+), 1072 deletions(-) diff --git a/app/actions.cpp b/app/actions.cpp index 4b418fac..114c860c 100644 --- a/app/actions.cpp +++ b/app/actions.cpp @@ -206,17 +206,17 @@ namespace Action { std::stringstream output(std::stringstream::out|std::stringstream::binary); result = printStructure(output, option, path); if ( result == 0 ) { - size_t size = static_cast(output.str().size()); - Exiv2::DataBuf iccProfile(static_cast(size)); - Exiv2::DataBuf ascii(static_cast(size * 3 + 1)); + size_t size = output.str().size(); + Exiv2::DataBuf iccProfile(size); + Exiv2::DataBuf ascii(size * 3 + 1); ascii.write_uint8(size * 3, 0); iccProfile.copyBytes(0,output.str().c_str(),size); if (Exiv2::base64encode(iccProfile.c_data(), size, reinterpret_cast(ascii.data()), size * 3)) { long chunk = 60 ; - std::string code = std::string("data:") + std::string(ascii.c_str()); - long length = static_cast(code.size()); - for ( long start = 0 ; start < length ; start += chunk ) { - long count = (start+chunk) < length ? chunk : length - start ; + std::string code = std::string("data:") + ascii.c_str(); + size_t length = code.size(); + for ( size_t start = 0 ; start < length ; start += chunk ) { + size_t count = (start+chunk) < length ? chunk : length - start ; std::cout << code.substr(start,count) << std::endl; } } @@ -306,7 +306,7 @@ namespace Action { } else { auto dataBuf = exifThumb.copy(); - if (dataBuf.size() == 0) { + if (dataBuf.empty()) { std::cout << _("None"); } else { @@ -569,7 +569,7 @@ namespace Action { std::ostringstream os; // #1114 - show negative values for SByte if (md.typeId() == Exiv2::signedByte) { - for ( long c = 0 ; c < md.value().count() ; c++ ) { + for ( size_t c = 0 ; c < md.value().count() ; c++ ) { const auto value = md.value().toInt64(c); os << (c?" ":"") << std::dec << (value < 128 ? value : value - 256); } @@ -591,7 +591,7 @@ namespace Action { std::cout << std::endl; Exiv2::DataBuf buf(md.size()); md.copy(buf.data(), pImage->byteOrder()); - Exiv2::hexdump(std::cout, buf.c_data(), buf.size()); + Exiv2::hexdump(std::cout, buf.c_data(), static_cast(buf.size())); } std::cout << std::endl; return true; @@ -913,8 +913,7 @@ namespace Action { else { if ( (Params::instance().target_ & Params::ctStdInOut) != 0 ) { Exiv2::DataBuf buf = exifThumb.copy(); - std::cout.write(reinterpret_cast(buf.data()), - buf.size()); + std::cout.write(buf.c_str(), buf.size()); return 0; } @@ -929,7 +928,7 @@ namespace Action { << thumbPath << std::endl; } } - rc = exifThumb.writeFile(thumb); + rc = static_cast(exifThumb.writeFile(thumb)); if (rc == 0) { std::cerr << path_ << ": " << _("Exif data doesn't contain a thumbnail\n"); } @@ -992,15 +991,14 @@ namespace Action { } else { if ( bStdout ) { // -eC- - std::cout.write(image->iccProfile().c_str(), - image->iccProfile().size()); + std::cout.write(image->iccProfile().c_str(), image->iccProfile().size()); } else { if (Params::instance().verbose_) { std::cout << _("Writing iccProfile: ") << target << std::endl; } Exiv2::FileIo iccFile(target); iccFile.open("wb") ; - iccFile.write(image->iccProfile().c_data(),image->iccProfile().size()); + iccFile.write(image->iccProfile().c_data(), image->iccProfile().size()); iccFile.close(); } } @@ -1024,7 +1022,7 @@ namespace Action { std::cout << pvImg.size() << " " << _("bytes") << ") " << _("to file") << " " << pvPath << std::endl; } - long rc = pvImg.writeFile(pvFile); + auto rc = pvImg.writeFile(pvFile); if (rc == 0) { std::cerr << path_ << ": " << _("Image does not have preview") << " " << num << "\n"; @@ -1089,7 +1087,7 @@ namespace Action { return 1; } // Insert::run - int Insert::insertXmpPacket(const std::string& path,const std::string& xmpPath) + int Insert::insertXmpPacket(const std::string& path,const std::string& xmpPath) { int rc = 0; bool bStdin = xmpPath == "-" ; @@ -1120,7 +1118,7 @@ namespace Action { int Insert::insertXmpPacket(const std::string& path, const Exiv2::DataBuf& xmpBlob, bool usePacket) { std::string xmpPacket; - for ( long i = 0 ; i < xmpBlob.size() ; i++ ) { + for ( size_t i = 0 ; i < xmpBlob.size() ; i++ ) { xmpPacket += static_cast(xmpBlob.read_uint8(i)); } auto image = Exiv2::ImageFactory::open(path); @@ -1134,7 +1132,7 @@ namespace Action { return 0; } - int Insert::insertIccProfile(const std::string& path,const std::string& iccPath) + int Insert::insertIccProfile(const std::string& path,const std::string& iccPath) { int rc = 0; // for path "foo.XXX", do a binary copy of "foo.icc" @@ -1825,7 +1823,7 @@ namespace { Exiv2::Image::UniquePtr sourceImage; if ( bStdin ) { Params::instance().getStdin(stdIn); - auto ioStdin = std::make_unique(stdIn.c_data(),stdIn.size()); + auto ioStdin = std::make_unique(stdIn.c_data(), stdIn.size()); sourceImage = Exiv2::ImageFactory::open(std::move(ioStdin)); } else { sourceImage = Exiv2::ImageFactory::open(source); diff --git a/app/exiv2.cpp b/app/exiv2.cpp index 6b1162dd..3a93bcb4 100644 --- a/app/exiv2.cpp +++ b/app/exiv2.cpp @@ -987,7 +987,7 @@ static int readFileToBuf(FILE* f,Exiv2::DataBuf& buf) void Params::getStdin(Exiv2::DataBuf& buf) { // copy stdin to stdinBuf - if ( stdinBuf.size() == 0 ) { + if (stdinBuf.empty()) { #if defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW__) || defined(_MSC_VER) DWORD fdwMode; _setmode(fileno(stdin), O_BINARY); @@ -1012,7 +1012,7 @@ void Params::getStdin(Exiv2::DataBuf& buf) // this is only used to simulate reading from stdin when debugging // to simulate exiv2 -pX foo.jpg | exiv2 -iXX- bar.jpg // exiv2 -pX foo.jpg > ~/temp/stdin ; exiv2 -iXX- bar.jpg - if ( stdinBuf.size() == 0 ) { + if ( stdinBuf.empty()) { const char* path = "/Users/rmills/temp/stdin"; FILE* f = fopen(path,"rb"); if ( f ) { @@ -1043,7 +1043,7 @@ int Params::getopt(int argc, char* const Argv[]) std::vector argv(argc+1); argv[argc] = nullptr; - std::unordered_map longs { + const std::unordered_map longs { {"--adjust" , "-a"}, {"--binary" , "-b"}, {"--comment" , "-c"}, @@ -1080,7 +1080,7 @@ int Params::getopt(int argc, char* const Argv[]) for ( int i = 0 ; i < argc ; i++ ) { std::string arg(Argv[i]); if (longs.find(arg) != longs.end() ) { - argv[i] = ::strdup(longs[arg].c_str()); + argv[i] = ::strdup(longs.at(arg).c_str()); } else { argv[i] = ::strdup(Argv[i]); } diff --git a/include/exiv2/basicio.hpp b/include/exiv2/basicio.hpp index cdd2ec42..9dd17e36 100644 --- a/include/exiv2/basicio.hpp +++ b/include/exiv2/basicio.hpp @@ -100,7 +100,7 @@ namespace Exiv2 { @return Number of bytes written to IO source successfully;
0 if failure; */ - virtual long write(const byte* data, long wcount) = 0; + virtual size_t write(const byte* data, size_t wcount) = 0; /*! @brief Write data that is read from another BasicIo instance to the IO source. Current IO position is advanced by the number @@ -110,7 +110,7 @@ namespace Exiv2 { @return Number of bytes written to IO source successfully;
0 if failure; */ - virtual long write(BasicIo& src) = 0; + virtual size_t write(BasicIo& src) = 0; /*! @brief Write one byte to the IO source. Current IO position is advanced by one byte. @@ -129,7 +129,7 @@ namespace Exiv2 { DataBuf::size_ member to find the number of bytes read. DataBuf::size_ will be 0 on failure. */ - virtual DataBuf read(long rcount) = 0; + virtual DataBuf read(size_t rcount) = 0; /*! @brief Read data from the IO source. Reading starts at the current IO position and the position is advanced by the number of bytes @@ -142,7 +142,7 @@ namespace Exiv2 { @return Number of bytes read from IO source successfully;
0 if failure; */ - virtual long read(byte* buf, long rcount) = 0; + virtual size_t read(byte* buf, size_t rcount) = 0; /*! @brief Safe version of `read()` that checks for errors and throws an exception if the read was unsuccessful. @@ -153,7 +153,7 @@ namespace Exiv2 { read if \em rcount bytes are not available. @param err Error code to use if an exception is thrown. */ - void readOrThrow(byte* buf, long rcount, ErrorCode err); + void readOrThrow(byte* buf, size_t rcount, ErrorCode err); /*! @brief Read one byte from the IO source. Current IO position is advanced by one byte. @@ -352,7 +352,7 @@ namespace Exiv2 { @return Number of bytes written to the file successfully;
0 if failure; */ - long write(const byte* data, long wcount) override; + size_t write(const byte* data, size_t wcount) override; /*! @brief Write data that is read from another BasicIo instance to the file. The file position is advanced by the number @@ -362,7 +362,7 @@ namespace Exiv2 { @return Number of bytes written to the file successfully;
0 if failure; */ - long write(BasicIo& src) override; + size_t write(BasicIo& src) override; /*! @brief Write one byte to the file. The file position is advanced by one byte. @@ -381,7 +381,7 @@ namespace Exiv2 { DataBuf::size_ member to find the number of bytes read. DataBuf::size_ will be 0 on failure. */ - DataBuf read(long rcount) override; + DataBuf read(size_t rcount) override; /*! @brief Read data from the file. Reading starts at the current file position and the position is advanced by the number of @@ -394,7 +394,7 @@ namespace Exiv2 { @return Number of bytes read from the file successfully;
0 if failure; */ - long read(byte* buf, long rcount) override; + size_t read(byte* buf, size_t rcount) override; /*! @brief Read one byte from the file. The file position is advanced by one byte. @@ -519,11 +519,10 @@ namespace Exiv2 { @brief Constructor that accepts a block of memory. A copy-on-write algorithm allows read operations directly from the original data and will create a copy of the buffer on the first write operation. - @param data Pointer to data. Data must be at least \em size - bytes long + @param data Pointer to data. Data must be at least \em size bytes long @param size Number of bytes to copy. */ - MemIo(const byte* data, long size); + MemIo(const byte* data, size_t size); //! Destructor. Releases all managed memory ~MemIo() override; //@} @@ -552,7 +551,7 @@ namespace Exiv2 { @return Number of bytes written to the memory block successfully;
0 if failure; */ - long write(const byte* data, long wcount) override; + size_t write(const byte* data, size_t wcount) override; /*! @brief Write data that is read from another BasicIo instance to the memory block. If needed, the size of the internal memory @@ -563,7 +562,7 @@ namespace Exiv2 { @return Number of bytes written to the memory block successfully;
0 if failure; */ - long write(BasicIo& src) override; + size_t write(BasicIo& src) override; /*! @brief Write one byte to the memory block. The IO position is advanced by one byte. @@ -582,7 +581,7 @@ namespace Exiv2 { DataBuf::size_ member to find the number of bytes read. DataBuf::size_ will be 0 on failure. */ - DataBuf read(long rcount) override; + DataBuf read(size_t rcount) override; /*! @brief Read data from the memory block. Reading starts at the current IO position and the position is advanced by the number of @@ -595,7 +594,7 @@ namespace Exiv2 { @return Number of bytes read from the memory block successfully;
0 if failure; */ - long read(byte* buf, long rcount) override; + size_t read(byte* buf, size_t rcount) override; /*! @brief Read one byte from the memory block. The IO position is advanced by one byte. @@ -791,7 +790,7 @@ namespace Exiv2 { @brief Not support this method. @return 0 means failure */ - long write(const byte* data, long wcount) override; + size_t write(const byte* data, size_t wcount) override; /*! @brief Write data that is read from another BasicIo instance to the remote file. @@ -806,7 +805,7 @@ namespace Exiv2 { @note The write access is only supported by http, https, ssh. */ - long write(BasicIo& src) override; + size_t write(BasicIo& src) override; /*! @brief Not support @@ -825,7 +824,7 @@ namespace Exiv2 { DataBuf::size_ member to find the number of bytes read. DataBuf::size_ will be 0 on failure. */ - DataBuf read(long rcount) override; + DataBuf read(size_t rcount) override; /*! @brief Read data from the memory blocks. Reading starts at the current IO position and the position is advanced by the number of @@ -840,7 +839,7 @@ namespace Exiv2 { @return Number of bytes read from the memory block successfully;
0 if failure; */ - long read(byte* buf, long rcount) override; + size_t read(byte* buf, size_t rcount) override; /*! @brief Read one byte from the memory blocks. The IO position is advanced by one byte. @@ -974,13 +973,13 @@ namespace Exiv2 { will call RemoteIo::write(const byte* data, long wcount) if the write access is available for the protocol. Otherwise, it throws the Error. */ - long write(const byte* data, long wcount) override; + size_t write(const byte* data, size_t wcount) override; /*! @brief Write access is only available for some protocols. This method will call RemoteIo::write(BasicIo& src) if the write access is available for the protocol. Otherwise, it throws the Error. */ - long write(BasicIo& src) override; + size_t write(BasicIo& src) override; // NOT IMPLEMENTED //! Copy constructor @@ -1008,7 +1007,7 @@ namespace Exiv2 { @return Return the number of bytes written. @throw Error In case of failure. */ - EXIV2API long writeFile(const DataBuf& buf, const std::string& path); + EXIV2API size_t writeFile(const DataBuf& buf, const std::string& path); #ifdef EXV_USE_CURL /*! @brief The callback function is called by libcurl to write the data diff --git a/include/exiv2/bmffimage.hpp b/include/exiv2/bmffimage.hpp index abed178e..05a6f6c0 100644 --- a/include/exiv2/bmffimage.hpp +++ b/include/exiv2/bmffimage.hpp @@ -118,10 +118,10 @@ namespace Exiv2 std::ostream &out, bool bTrace, uint8_t version, - uint32_t width_offset, - uint32_t height_offset, - uint32_t size_offset, - uint32_t relative_position); + size_t width_offset, + size_t height_offset, + size_t size_offset, + size_t relative_position); //@} //! @name Manipulators @@ -138,7 +138,7 @@ namespace Exiv2 uint32_t pixelWidth() const override; uint32_t pixelHeight() const override; //@} - + Exiv2::ByteOrder endian_{Exiv2::bigEndian}; private: diff --git a/include/exiv2/exif.hpp b/include/exiv2/exif.hpp index 6feb92d4..3ded2ef2 100644 --- a/include/exiv2/exif.hpp +++ b/include/exiv2/exif.hpp @@ -145,7 +145,7 @@ namespace Exiv2 { @return Return -1 if the %Exifdatum does not have a value yet or the value has no data area, else 0. */ - int setDataArea(const byte* buf, long len); + int setDataArea(const byte* buf, size_t len); //@} //! @name Accessors @@ -183,7 +183,7 @@ namespace Exiv2 { //! Return the size in bytes of one component of this type long typeSize() const override; //! Return the number of components in the value - long count() const override; + size_t count() const override; //! Return the size of the value in bytes long size() const override; //! Return the value as a string. @@ -195,7 +195,7 @@ namespace Exiv2 { Value::UniquePtr getValue() const override; const Value& value() const override; //! Return the size of the data area. - long sizeDataArea() const; + size_t sizeDataArea() const; /*! @brief Return a copy of the data area of the value. The caller owns this copy and %DataBuf ensures that it will be deleted. @@ -254,7 +254,7 @@ namespace Exiv2 { @param path File name of the thumbnail without extension. @return The number of bytes written. */ - long writeFile(const std::string& path) const; + size_t writeFile(const std::string& path) const; /*! @brief Return the MIME type of the thumbnail, either \c "image/tiff" or \c "image/jpeg". @@ -311,12 +311,7 @@ namespace Exiv2 { applications may have problems with that. (The preview application that comes with OS X for one.) - David Harvey. */ - void setJpegThumbnail( - const std::string& path, - URational xres, - URational yres, - uint16_t unit - ); + void setJpegThumbnail(const std::string& path, URational xres, URational yres, uint16_t unit); /*! @brief Set the Exif thumbnail to the JPEG image pointed to by \em buf, and size \em size. Set XResolution, YResolution and @@ -334,13 +329,7 @@ namespace Exiv2 { applications may have problems with that. (The preview application that comes with OS X for one.) - David Harvey. */ - void setJpegThumbnail( - const byte* buf, - long size, - URational xres, - URational yres, - uint16_t unit - ); + void setJpegThumbnail(const byte* buf, size_t size, URational xres, URational yres, uint16_t unit); /*! @brief Set the Exif thumbnail to the JPEG image \em path. @@ -367,7 +356,7 @@ namespace Exiv2 { @note No checks on the image format or size are performed. @note Additional existing Exif thumbnail tags are not modified. */ - void setJpegThumbnail(const byte* buf, long size); + void setJpegThumbnail(const byte* buf, size_t size); /*! @brief Delete the thumbnail from the Exif data. Removes all Exif.%Thumbnail.*, i.e., Exif IFD1 tags. @@ -474,15 +463,14 @@ namespace Exiv2 { */ const_iterator findKey(const ExifKey& key) const; //! Return true if there is no Exif metadata - bool empty() const { return count() == 0; } + bool empty() const { return exifMetadata_.empty(); } //! Get the number of metadata entries - long count() const { return static_cast(exifMetadata_.size()); } + size_t count() const { return exifMetadata_.size(); } //@} private: // DATA ExifMetadata exifMetadata_; - }; // class ExifData /*! @@ -506,11 +494,7 @@ namespace Exiv2 { @param size Length of the data buffer @return Byte order in which the data is encoded. */ - static ByteOrder decode( - ExifData& exifData, - const byte* pData, - uint32_t size - ); + static ByteOrder decode(ExifData& exifData, const byte* pData, size_t size); /*! @brief Encode Exif metadata from the provided metadata to binary Exif format. @@ -552,7 +536,7 @@ namespace Exiv2 { static WriteMethod encode( Blob& blob, const byte* pData, - uint32_t size, + size_t size, ByteOrder byteOrder, const ExifData& exifData ); diff --git a/include/exiv2/image.hpp b/include/exiv2/image.hpp index 36adf69e..8cd7407d 100644 --- a/include/exiv2/image.hpp +++ b/include/exiv2/image.hpp @@ -561,7 +561,7 @@ namespace Exiv2 { matches that of the data buffer. @throw Error If the memory contains data of an unknown image type. */ - static Image::UniquePtr open(const byte* data, long size); + static Image::UniquePtr open(const byte* data, size_t size); /*! @brief Create an Image subclass of the appropriate type by reading the provided BasicIo instance. %Image type is derived from the @@ -630,7 +630,7 @@ namespace Exiv2 { @param size Number of bytes pointed to by \em data. @return %Image type or Image::none if the type is not recognized. */ - static ImageType getType(const byte* data, long size); + static ImageType getType(const byte* data, size_t size); /*! @brief Returns the image type of data provided by a BasicIo instance. The passed in \em io instance is (re)opened by this method. @@ -684,7 +684,7 @@ namespace Exiv2 { // template, inline and free functions //! Append \em len bytes pointed to by \em buf to \em blob. - EXIV2API void append(Exiv2::Blob& blob, const byte* buf, uint32_t len); + EXIV2API void append(Exiv2::Blob& blob, const byte* buf, size_t len); } // namespace Exiv2 diff --git a/include/exiv2/iptc.hpp b/include/exiv2/iptc.hpp index 4ea0d03d..df241b5e 100644 --- a/include/exiv2/iptc.hpp +++ b/include/exiv2/iptc.hpp @@ -136,7 +136,7 @@ namespace Exiv2 { TypeId typeId() const override; const char* typeName() const override; long typeSize() const override; - long count() const override; + size_t count() const override; long size() const override; std::string toString() const override; std::string toString(long n) const override; @@ -291,23 +291,17 @@ namespace Exiv2 { @return 0 if successful;
5 if the binary IPTC data is invalid or corrupt */ - static int decode( - IptcData& iptcData, - const byte* pData, - uint32_t size - ); + static int decode(IptcData& iptcData, const byte* pData, uint32_t size); + /*! - @brief Encode the IPTC datasets from \em iptcData to a binary - representation in IPTC IIM4 format. + @brief Encode the IPTC datasets from \em iptcData to a binary representation in IPTC IIM4 format. Convert the IPTC datasets to binary format and return it. Caller owns the returned buffer. The copied data follows the IPTC IIM4 standard. @return Data buffer containing the binary IPTC data in IPTC IIM4 format. */ - static DataBuf encode( - const IptcData& iptcData - ); + static DataBuf encode(const IptcData& iptcData); private: // Constant data diff --git a/include/exiv2/jpgimage.hpp b/include/exiv2/jpgimage.hpp index 46c14867..9ed64aeb 100644 --- a/include/exiv2/jpgimage.hpp +++ b/include/exiv2/jpgimage.hpp @@ -57,8 +57,7 @@ namespace Exiv2 { @return true if the IRB marker is known and the buffer is big enough to check this;
false otherwise */ - static bool isIrb(const byte* pPsData, - long sizePsData); + static bool isIrb(const byte* pPsData, size_t sizePsData); /*! @brief Validates all IRBs @@ -67,8 +66,7 @@ namespace Exiv2 { @return true if all IRBs are valid;
false otherwise */ - static bool valid(const byte* pPsData, - long sizePsData); + static bool valid(const byte* pPsData, size_t sizePsData); /*! @brief Locates the data for a %Photoshop tag in a %Photoshop formated memory buffer. Operates on raw data to simplify reuse. @@ -87,7 +85,7 @@ namespace Exiv2 { -2 if the pPsData buffer does not contain valid data. */ static int locateIrb(const byte *pPsData, - long sizePsData, + size_t sizePsData, uint16_t psTag, const byte **record, uint32_t *const sizeHdr, @@ -96,7 +94,7 @@ namespace Exiv2 { @brief Forwards to locateIrb() with \em psTag = \em iptc_ */ static int locateIptcIrb(const byte *pPsData, - long sizePsData, + size_t sizePsData, const byte **record, uint32_t *const sizeHdr, uint32_t *const sizeData); @@ -104,7 +102,7 @@ namespace Exiv2 { @brief Forwards to locatePreviewIrb() with \em psTag = \em preview_ */ static int locatePreviewIrb(const byte *pPsData, - long sizePsData, + size_t sizePsData, const byte **record, uint32_t *const sizeHdr, uint32_t *const sizeData); @@ -117,9 +115,7 @@ namespace Exiv2 { @param iptcData Iptc data to embed, may be empty @return A data buffer containing the new IRB buffer, may have 0 size */ - static DataBuf setIptcIrb(const byte* pPsData, - long sizePsData, - const IptcData& iptcData); + static DataBuf setIptcIrb(const byte* pPsData, size_t sizePsData, const IptcData& iptcData); }; // class Photoshop @@ -132,13 +128,6 @@ namespace Exiv2 { //@{ void readMetadata() override; void writeMetadata() override; - - /*! - @brief Print out the structure of image file. - @throw Error if reading of the file fails or the image data is - not valid (does not look like data of the specific image type). - @warning This function is not thread safe and intended for exiv2 -pS for debugging. - */ void printStructure(std::ostream& out, PrintStructureOption option, int depth) override; //@} @@ -177,7 +166,7 @@ namespace Exiv2 { BasicIo::UniquePtr io, bool create, const byte initData[], - long dataSize); + size_t dataSize); //@} //! @name Accessors @@ -254,7 +243,7 @@ namespace Exiv2 { @return 0 if successful;
4 if the image can not be written to. */ - int initImage(const byte initData[], long dataSize); + int initImage(const byte initData[], size_t dataSize); /*! @brief Provides the main implementation of writeMetadata() by writing all buffered metadata to the provided BasicIo. diff --git a/include/exiv2/metadatum.hpp b/include/exiv2/metadatum.hpp index 53efd85a..73c88b83 100644 --- a/include/exiv2/metadatum.hpp +++ b/include/exiv2/metadatum.hpp @@ -206,7 +206,7 @@ namespace Exiv2 { //! Return the size in bytes of one component of this type virtual long typeSize() const =0; //! Return the number of components in the value - virtual long count() const =0; + virtual size_t count() const =0; //! Return the size of the value in bytes virtual long size() const =0; //! Return the value as a string. diff --git a/include/exiv2/preview.hpp b/include/exiv2/preview.hpp index 6d5228d1..039f49f2 100644 --- a/include/exiv2/preview.hpp +++ b/include/exiv2/preview.hpp @@ -44,7 +44,7 @@ namespace Exiv2 { //! Preview image extension. std::string extension_; //! Preview image size in bytes. - uint32_t size_; + size_t size_; //! Preview image width in pixels or 0 for unknown width. uint32_t width_; //! Preview image height in pixels or 0 for unknown height. @@ -99,7 +99,7 @@ namespace Exiv2 { @param path File name of the preview image without extension. @return The number of bytes written. */ - long writeFile(const std::string& path) const; + size_t writeFile(const std::string& path) const; /*! @brief Return the MIME type of the preview image, usually either \c "image/tiff" or \c "image/jpeg". diff --git a/include/exiv2/tiffimage.hpp b/include/exiv2/tiffimage.hpp index c2344354..c5fedff4 100644 --- a/include/exiv2/tiffimage.hpp +++ b/include/exiv2/tiffimage.hpp @@ -135,7 +135,7 @@ namespace Exiv2 { IptcData& iptcData, XmpData& xmpData, const byte* pData, - uint32_t size + size_t size ); /*! @brief Encode metadata from the provided metadata to TIFF format. diff --git a/include/exiv2/types.hpp b/include/exiv2/types.hpp index 78c19196..f46a01f7 100644 --- a/include/exiv2/types.hpp +++ b/include/exiv2/types.hpp @@ -152,7 +152,7 @@ namespace Exiv2 { //! Return the type id for a type name static TypeId typeId(const std::string& typeName); //! Return the size in bytes of one element of this type - static long typeSize(TypeId typeId); + static size_t typeSize(TypeId typeId); }; @@ -168,9 +168,9 @@ namespace Exiv2 { //! Default constructor DataBuf() = default; //! Constructor with an initial buffer size - explicit DataBuf(long size); + explicit DataBuf(size_t size); //! Constructor, copies an existing buffer - DataBuf(const byte* pData, long size); + DataBuf(const byte* pData, size_t size); //@} //! @name Manipulators @@ -180,17 +180,25 @@ namespace Exiv2 { the requested \em size is less than the current buffer size, no new memory is allocated and the buffer size doesn't change. */ - void alloc(long size); + void alloc(size_t size); /*! @brief Resize the buffer. Existing data is preserved (like std::realloc()). */ - void resize(long size); + void resize(size_t size); //! Reset value void reset(); //@} - long size() const { return pData_.size(); } + using iterator = std::vector::iterator; + using const_iterator = std::vector::const_iterator; + + inline iterator begin() noexcept { return pData_.begin(); } + inline const_iterator cbegin() const noexcept { return pData_.cbegin(); } + inline iterator end() noexcept { return pData_.end(); } + inline const_iterator cend() const noexcept { return pData_.end(); } + + size_t size() const { return pData_.size(); } uint8_t read_uint8(size_t offset) const; void write_uint8(size_t offset, uint8_t x); @@ -219,6 +227,8 @@ namespace Exiv2 { //! Returns a (read-only) C-style string pointer. const char* c_str(size_t offset = 0) const; + bool empty() const {return pData_.empty(); } + private: std::vector pData_; }; diff --git a/include/exiv2/value.hpp b/include/exiv2/value.hpp index e75fedc0..08b4b33c 100644 --- a/include/exiv2/value.hpp +++ b/include/exiv2/value.hpp @@ -58,18 +58,17 @@ namespace Exiv2 { //! Virtual destructor. virtual ~Value() = default; //@} + //! @name Manipulators //@{ - /*! - @brief Read the value from a character buffer. - @param buf Pointer to the data buffer to read from - @param len Number of bytes in the data buffer - @param byteOrder Applicable byte order (little or big endian). + /// @brief Read the value from a character buffer. + /// @param buf Pointer to the data buffer to read from + /// @param len Number of bytes in the data buffer + /// @param byteOrder Applicable byte order (little or big endian). + /// @return 0 if successful. + virtual int read(const byte* buf, size_t len, ByteOrder byteOrder) =0; - @return 0 if successful. - */ - virtual int read(const byte* buf, long len, ByteOrder byteOrder) =0; /*! @brief Set the value from a string buffer. The format of the string corresponds to that of the write() method, i.e., a string @@ -93,7 +92,7 @@ namespace Exiv2 { @param len Size of the data area @return Return -1 if the value has no data area, else 0. */ - virtual int setDataArea(const byte* buf, long len); + virtual int setDataArea(const byte* buf, size_t len); //@} //! @name Accessors @@ -118,9 +117,9 @@ namespace Exiv2 { */ virtual long copy(byte* buf, ByteOrder byteOrder) const =0; //! Return the number of components of the value - virtual long count() const =0; + virtual size_t count() const =0; //! Return the size of the value in bytes - virtual long size() const =0; + virtual size_t size() const =0; /*! @brief Write the value to an output stream. You do not usually have to use this function; it is used for the implementation of @@ -139,7 +138,7 @@ namespace Exiv2 { of this method may be undefined if there is no n-th component. */ - virtual std::string toString(long n) const; + virtual std::string toString(size_t n) const; /*! @brief Convert the n-th component of the value to an int64_t. The behaviour of this method may be undefined if there is no @@ -147,7 +146,7 @@ namespace Exiv2 { @return The converted value. */ - virtual int64_t toInt64(long n =0) const =0; + virtual int64_t toInt64(size_t n =0) const =0; /*! @brief Convert the n-th component of the value to a float. The behaviour of this method may be undefined if there is no @@ -155,7 +154,7 @@ namespace Exiv2 { @return The converted value. */ - virtual uint32_t toUint32(long n =0) const =0; + virtual uint32_t toUint32(size_t n =0) const =0; /*! @brief Convert the n-th component of the value to a float. The behaviour of this method may be undefined if there is no @@ -163,7 +162,7 @@ namespace Exiv2 { @return The converted value. */ - virtual float toFloat(long n =0) const =0; + virtual float toFloat(size_t n =0) const =0; /*! @brief Convert the n-th component of the value to a Rational. The behaviour of this method may be undefined if there is no @@ -171,9 +170,9 @@ namespace Exiv2 { @return The converted value. */ - virtual Rational toRational(long n =0) const =0; + virtual Rational toRational(size_t n =0) const =0; //! Return the size of the data area, 0 if there is none. - virtual long sizeDataArea() const; + virtual size_t sizeDataArea() const; /*! @brief Return a copy of the data area if the value has one. The caller owns this copy and DataBuf ensures that it will be @@ -246,8 +245,7 @@ namespace Exiv2 { virtual Value* clone_() const =0; // DATA TypeId type_; //!< Type of the data - - }; // class Value + }; //! Output operator for Value types inline std::ostream& operator<<(std::ostream& os, const Value& value) @@ -271,19 +269,7 @@ namespace Exiv2 { //! @name Manipulators //@{ - /*! - @brief Read the value from a character buffer. - - @note The byte order is required by the interface but not - used by this method, so just use the default. - - @param buf Pointer to the data buffer to read from - @param len Number of bytes in the data buffer - @param byteOrder Byte order. Not needed. - - @return 0 if successful. - */ - int read(const byte* buf, long len, ByteOrder byteOrder = invalidByteOrder) override; + int read(const byte* buf, size_t len, ByteOrder byteOrder = invalidByteOrder) override; //! Set the data from a string of integer values (e.g., "0 1 2 3") int read(const std::string& buf) override; //@} @@ -305,19 +291,19 @@ namespace Exiv2 { @return Number of characters written. */ long copy(byte* buf, ByteOrder byteOrder = invalidByteOrder) const override; - long count() const override; - long size() const override; + size_t count() const override; + size_t size() const override; std::ostream& write(std::ostream& os) const override; /*! @brief Return the n-th component of the value as a string. The behaviour of this method may be undefined if there is no n-th component. */ - std::string toString(long n) const override; - int64_t toInt64(long n = 0) const override; - uint32_t toUint32(long n = 0) const override; - float toFloat(long n = 0) const override; - Rational toRational(long n = 0) const override; + std::string toString(size_t n) const override; + int64_t toInt64(size_t n = 0) const override; + uint32_t toUint32(size_t n = 0) const override; + float toFloat(size_t n = 0) const override; + Rational toRational(size_t n = 0) const override; //@} private: @@ -358,19 +344,7 @@ namespace Exiv2 { //@{ //! Read the value from buf. This default implementation uses buf as it is. int read(const std::string& buf) override; - /*! - @brief Read the value from a character buffer. - - @note The byte order is required by the interface but not used by this - method, so just use the default. - - @param buf Pointer to the data buffer to read from - @param len Number of bytes in the data buffer - @param byteOrder Byte order. Not needed. - - @return 0 if successful. - */ - int read(const byte* buf, long len, ByteOrder byteOrder = invalidByteOrder) override; + int read(const byte* buf, size_t len, ByteOrder byteOrder = invalidByteOrder) override; //@} //! @name Accessors @@ -390,12 +364,12 @@ namespace Exiv2 { @return Number of characters written. */ long copy(byte* buf, ByteOrder byteOrder = invalidByteOrder) const override; - long count() const override; - long size() const override; - int64_t toInt64(long n = 0) const override; - uint32_t toUint32(long n = 0) const override; - float toFloat(long n = 0) const override; - Rational toRational(long n = 0) const override; + size_t count() const override; + size_t size() const override; + int64_t toInt64(size_t n = 0) const override; + uint32_t toUint32(size_t n = 0) const override; + float toFloat(size_t n = 0) const override; + Rational toRational(size_t n = 0) const override; std::ostream& write(std::ostream& os) const override; //@} @@ -568,10 +542,7 @@ namespace Exiv2 { 1 if an invalid character set is encountered */ int read(const std::string& comment) override; - /*! - @brief Read the comment from a byte buffer. - */ - int read(const byte* buf, long len, ByteOrder byteOrder) override; + int read(const byte* buf, size_t len, ByteOrder byteOrder) override; //@} //! @name Accessors @@ -646,7 +617,7 @@ namespace Exiv2 { XmpArrayType xmpArrayType() const; //! Return XMP struct, indicates if an XMP value is a structure. XmpStruct xmpStruct() const; - long size() const override; + size_t size() const override; /*! @brief Write value to a character data buffer. @@ -669,21 +640,9 @@ namespace Exiv2 { void setXmpArrayType(XmpArrayType xmpArrayType); //! Set the XMP struct type to indicate that an XMP value is a structure. void setXmpStruct(XmpStruct xmpStruct =xsStruct); - /*! - @brief Read the value from a character buffer. - - Uses read(const std::string& buf) - @note The byte order is required by the interface but not used by this - method, so just use the default. - - @param buf Pointer to the data buffer to read from - @param len Number of bytes in the data buffer - @param byteOrder Byte order. Not needed. - - @return 0 if successful. - */ - int read(const byte* buf, long len, ByteOrder byteOrder = invalidByteOrder) override; + /// @note Uses read(const std::string& buf) + int read(const byte* buf, size_t len, ByteOrder byteOrder = invalidByteOrder) override; int read(const std::string& buf) override = 0; //@} @@ -744,36 +703,36 @@ namespace Exiv2 { //! @name Accessors //@{ UniquePtr clone() const; - long size() const override; - long count() const override; + size_t size() const override; + size_t count() const override; /*! @brief Convert the value to an int64_t. The optional parameter \em n is not used and is ignored. @return The converted value. */ - int64_t toInt64(long n = 0) const override; + int64_t toInt64(size_t n = 0) const override; /*! @brief Convert the value to an uint32_t. The optional parameter \em n is not used and is ignored. @return The converted value. */ - uint32_t toUint32(long n = 0) const override; + uint32_t toUint32(size_t n = 0) const override; /*! @brief Convert the value to a float. The optional parameter \em n is not used and is ignored. @return The converted value. */ - float toFloat(long n = 0) const override; + float toFloat(size_t n = 0) const override; /*! @brief Convert the value to a Rational. The optional parameter \em n is not used and is ignored. @return The converted value. */ - Rational toRational(long n = 0) const override; + Rational toRational(size_t n = 0) const override; std::ostream& write(std::ostream& os) const override; //@} @@ -826,17 +785,17 @@ namespace Exiv2 { //! @name Accessors //@{ UniquePtr clone() const; - long count() const override; + size_t count() const override; /*! @brief Return the n-th component of the value as a string. The behaviour of this method may be undefined if there is no n-th component. */ - std::string toString(long n) const override; - int64_t toInt64(long n = 0) const override; - uint32_t toUint32(long n = 0) const override; - float toFloat(long n = 0) const override; - Rational toRational(long n = 0) const override; + std::string toString(size_t n) const override; + int64_t toInt64(size_t n = 0) const override; + uint32_t toUint32(size_t n = 0) const override; + float toFloat(size_t n = 0) const override; + Rational toRational(size_t n = 0) const override; /*! @brief Write all elements of the value to \em os, separated by commas. @@ -925,7 +884,7 @@ namespace Exiv2 { //! @name Accessors //@{ UniquePtr clone() const; - long count() const override; + size_t count() const override; /*! @brief Return the text value associated with the default language qualifier \c x-default. The parameter \em n is not used, but @@ -933,17 +892,17 @@ namespace Exiv2 { string and sets the ok-flag to \c false if there is no default value. */ - std::string toString(long n) const override; + std::string toString(size_t n) const override; /*! @brief Return the text value associated with the language qualifier \em qualifier. Returns an empty string and sets the ok-flag to \c false if there is no entry for the language qualifier. */ std::string toString(const std::string& qualifier) const; - int64_t toInt64(long n = 0) const override; - uint32_t toUint32(long n = 0) const override; - float toFloat(long n = 0) const override; - Rational toRational(long n = 0) const override; + int64_t toInt64(size_t n = 0) const override; + uint32_t toUint32(size_t n = 0) const override; + float toFloat(size_t n = 0) const override; + Rational toRational(size_t n = 0) const override; /*! @brief Write all elements of the value to \em os, separated by commas. @@ -999,20 +958,10 @@ namespace Exiv2 { //! @name Manipulators //@{ - /*! - @brief Read the value from a character buffer. - - @note The byte order is required by the interface but not used by this - method, so just use the default. - - @param buf Pointer to the data buffer to read from - @param len Number of bytes in the data buffer - @param byteOrder Byte order. Not needed. - @return 0 if successful
- 1 in case of an unsupported date format - */ - int read(const byte* buf, long len, ByteOrder byteOrder = invalidByteOrder) override; + /// @return 0 if successful
+ /// 1 in case of an unsupported date format + int read(const byte* buf, size_t len, ByteOrder byteOrder = invalidByteOrder) override; /*! @brief Set the value to that of the string buf. @@ -1046,17 +995,17 @@ namespace Exiv2 { //! Return date struct containing date information virtual const Date& getDate() const; - long count() const override; - long size() const override; + size_t count() const override; + size_t size() const override; std::ostream& write(std::ostream& os) const override; //! Return the value as a UNIX calender time converted to int64_t. - int64_t toInt64(long n = 0) const override; + int64_t toInt64(size_t n = 0) const override; //! Return the value as a UNIX calender time converted to uint32_t. - uint32_t toUint32(long n = 0) const override; + uint32_t toUint32(size_t n = 0) const override; //! Return the value as a UNIX calender time converted to float. - float toFloat(long n = 0) const override; + float toFloat(size_t n = 0) const override; //! Return the value as a UNIX calender time converted to Rational. - Rational toRational(long n = 0) const override; + Rational toRational(size_t n = 0) const override; //@} private: @@ -1107,20 +1056,10 @@ namespace Exiv2 { //! @name Manipulators //@{ - /*! - @brief Read the value from a character buffer. - - @note The byte order is required by the interface but not used by this - method, so just use the default. - @param buf Pointer to the data buffer to read from - @param len Number of bytes in the data buffer - @param byteOrder Byte order. Not needed. - - @return 0 if successful
- 1 in case of an unsupported time format - */ - int read(const byte* buf, long len, ByteOrder byteOrder = invalidByteOrder) override; + /// @return 0 if successful
+ /// 1 in case of an unsupported time format + int read(const byte* buf, size_t len, ByteOrder byteOrder = invalidByteOrder) override; /*! @brief Set the value to that of the string buf. @@ -1153,17 +1092,17 @@ namespace Exiv2 { long copy(byte* buf, ByteOrder byteOrder = invalidByteOrder) const override; //! Return time struct containing time information virtual const Time& getTime() const; - long count() const override; - long size() const override; + size_t count() const override; + size_t size() const override; std::ostream& write(std::ostream& os) const override; //! Returns number of seconds in the day in UTC. - int64_t toInt64(long n = 0) const override; + int64_t toInt64(size_t n = 0) const override; //! Returns number of seconds in the day in UTC. - uint32_t toUint32(long n = 0) const override; + uint32_t toUint32(size_t n = 0) const override; //! Returns number of seconds in the day in UTC converted to float. - float toFloat(long n = 0) const override; + float toFloat(size_t n = 0) const override; //! Returns number of seconds in the day in UTC converted to Rational. - Rational toRational(long n = 0) const override; + Rational toRational(size_t n = 0) const override; //@} private: @@ -1233,7 +1172,7 @@ namespace Exiv2 { //@{ //! Assignment operator. ValueType& operator=(const ValueType& rhs); - int read(const byte* buf, long len, ByteOrder byteOrder) override; + int read(const byte* buf, size_t len, ByteOrder byteOrder) override; /*! @brief Set the data from a string of values of type T (e.g., "0 1 2 3" or "1/2 1/3 1/4" depending on what T is). @@ -1245,15 +1184,15 @@ namespace Exiv2 { @brief Set the data area. This method copies (clones) the buffer pointed to by buf. */ - int setDataArea(const byte* buf, long len) override; + int setDataArea(const byte* buf, size_t len) override; //@} //! @name Accessors //@{ UniquePtr clone() const { return UniquePtr(clone_()); } long copy(byte* buf, ByteOrder byteOrder) const override; - long count() const override; - long size() const override; + size_t count() const override; + size_t size() const override; std::ostream& write(std::ostream& os) const override; /*! @brief Return the n-th component of the value as a string. @@ -1261,13 +1200,13 @@ namespace Exiv2 { n-th component. */ - std::string toString(long n) const override; - int64_t toInt64(long n = 0) const override; - uint32_t toUint32(long n = 0) const override; - float toFloat(long n = 0) const override; - Rational toRational(long n = 0) const override; + std::string toString(size_t n) const override; + int64_t toInt64(size_t n = 0) const override; + uint32_t toUint32(size_t n = 0) const override; + float toFloat(size_t n = 0) const override; + Rational toRational(size_t n = 0) const override; //! Return the size of the data area. - long sizeDataArea() const override; + size_t sizeDataArea() const override; /*! @brief Return a copy of the data area in a DataBuf. The caller owns this copy and DataBuf ensures that it will be deleted. @@ -1294,7 +1233,7 @@ namespace Exiv2 { private: //! Utility for toInt64, toUint32, etc. template - inline I float_to_integer_helper(long n) const { + inline I float_to_integer_helper(size_t n) const { const auto v = value_.at(n); if (static_cast(std::numeric_limits::min()) <= v && v <= static_cast(std::numeric_limits::max())) { @@ -1306,7 +1245,7 @@ namespace Exiv2 { //! Utility for toInt64, toUint32, etc. template - inline I rational_to_integer_helper(long n) const { + inline I rational_to_integer_helper(size_t n) const { const auto& t = value_.at(n); const auto a = t.first; const auto b = t.second; @@ -1355,7 +1294,7 @@ namespace Exiv2 { //! Pointer to the buffer, nullptr if none has been allocated byte* pDataArea_{nullptr}; //! The current size of the buffer - long sizeDataArea_{0}; + size_t sizeDataArea_{0}; }; // class ValueType //! Unsigned short value type @@ -1586,13 +1525,13 @@ namespace Exiv2 { } template - int ValueType::read(const byte* buf, long len, ByteOrder byteOrder) + int ValueType::read(const byte* buf, size_t len, ByteOrder byteOrder) { value_.clear(); - long ts = TypeInfo::typeSize(typeId()); + size_t ts = TypeInfo::typeSize(typeId()); if (ts > 0) if (len % ts != 0) len = (len / ts) * ts; - for (long i = 0; i < len; i += ts) { + for (size_t i = 0; i < len; i += ts) { value_.push_back(getValue(buf + i, byteOrder)); } return 0; @@ -1624,13 +1563,13 @@ namespace Exiv2 { } template - long ValueType::count() const + size_t ValueType::count() const { - return static_cast(value_.size()); + return value_.size(); } template - long ValueType::size() const + size_t ValueType::size() const { return static_cast(TypeInfo::typeSize(typeId()) * value_.size()); } @@ -1655,7 +1594,7 @@ namespace Exiv2 { } template - std::string ValueType::toString(long n) const + std::string ValueType::toString(size_t n) const { ok_ = true; return Exiv2::toString(value_.at(n)); @@ -1663,13 +1602,13 @@ namespace Exiv2 { // Default implementation template - int64_t ValueType::toInt64(long n) const + int64_t ValueType::toInt64(size_t n) const { ok_ = true; return static_cast(value_.at(n)); } template - uint32_t ValueType::toUint32(long n) const + uint32_t ValueType::toUint32(size_t n) const { ok_ = true; return static_cast(value_.at(n)); @@ -1678,58 +1617,59 @@ namespace Exiv2 { #define LARGE_INT 1000000 // Specialization for double template<> - inline int64_t ValueType::toInt64(long n) const + inline int64_t ValueType::toInt64(size_t n) const { return float_to_integer_helper(n); } + template<> - inline uint32_t ValueType::toUint32(long n) const + inline uint32_t ValueType::toUint32(size_t n) const { return float_to_integer_helper(n); } // Specialization for float template<> - inline int64_t ValueType::toInt64(long n) const + inline int64_t ValueType::toInt64(size_t n) const { return float_to_integer_helper(n); } template<> - inline uint32_t ValueType::toUint32(long n) const + inline uint32_t ValueType::toUint32(size_t n) const { return float_to_integer_helper(n); } // Specialization for rational template<> - inline int64_t ValueType::toInt64(long n) const + inline int64_t ValueType::toInt64(size_t n) const { return rational_to_integer_helper(n); } template<> - inline uint32_t ValueType::toUint32(long n) const + inline uint32_t ValueType::toUint32(size_t n) const { return rational_to_integer_helper(n); } // Specialization for unsigned rational template<> - inline int64_t ValueType::toInt64(long n) const + inline int64_t ValueType::toInt64(size_t n) const { return rational_to_integer_helper(n); } template<> - inline uint32_t ValueType::toUint32(long n) const + inline uint32_t ValueType::toUint32(size_t n) const { return rational_to_integer_helper(n); } // Default implementation template - float ValueType::toFloat(long n) const + float ValueType::toFloat(size_t n) const { ok_ = true; return static_cast(value_.at(n)); } // Specialization for rational template<> - inline float ValueType::toFloat(long n) const + inline float ValueType::toFloat(size_t n) const { ok_ = (value_.at(n).second != 0); if (!ok_) return 0.0f; @@ -1737,7 +1677,7 @@ namespace Exiv2 { } // Specialization for unsigned rational template<> - inline float ValueType::toFloat(long n) const + inline float ValueType::toFloat(size_t n) const { ok_ = (value_.at(n).second != 0); if (!ok_) return 0.0f; @@ -1745,28 +1685,28 @@ namespace Exiv2 { } // Default implementation template - Rational ValueType::toRational(long n) const + Rational ValueType::toRational(size_t n) const { ok_ = true; return {value_.at(n), 1}; } // Specialization for rational template<> - inline Rational ValueType::toRational(long n) const + inline Rational ValueType::toRational(size_t n) const { ok_ = true; return {value_.at(n).first, value_.at(n).second}; } // Specialization for unsigned rational template<> - inline Rational ValueType::toRational(long n) const + inline Rational ValueType::toRational(size_t n) const { ok_ = true; return {value_.at(n).first, value_.at(n).second}; } // Specialization for float. template<> - inline Rational ValueType::toRational(long n) const + inline Rational ValueType::toRational(size_t n) const { ok_ = true; // Warning: This is a very simple conversion, see floatToRationalCast() @@ -1774,7 +1714,7 @@ namespace Exiv2 { } // Specialization for double. template<> - inline Rational ValueType::toRational(long n) const + inline Rational ValueType::toRational(size_t n) const { ok_ = true; // Warning: This is a very simple conversion, see floatToRationalCast() @@ -1782,7 +1722,7 @@ namespace Exiv2 { } template - long ValueType::sizeDataArea() const + size_t ValueType::sizeDataArea() const { return sizeDataArea_; } @@ -1794,7 +1734,7 @@ namespace Exiv2 { } template - int ValueType::setDataArea(const byte* buf, long len) + int ValueType::setDataArea(const byte* buf, size_t len) { byte* tmp = nullptr; if (len > 0) { diff --git a/include/exiv2/xmp_exiv2.hpp b/include/exiv2/xmp_exiv2.hpp index 85250a14..83383c7b 100644 --- a/include/exiv2/xmp_exiv2.hpp +++ b/include/exiv2/xmp_exiv2.hpp @@ -131,7 +131,7 @@ namespace Exiv2 { // Todo: Remove this method from the baseclass //! The Exif typeSize doesn't make sense here. Return 0. long typeSize() const override; - long count() const override; + size_t count() const override; long size() const override; std::string toString() const override; std::string toString(long n) const override; diff --git a/samples/addmoddel.cpp b/samples/addmoddel.cpp index bc3648b3..b858f7a6 100644 --- a/samples/addmoddel.cpp +++ b/samples/addmoddel.cpp @@ -98,7 +98,7 @@ try { // Get a pointer to a copy of the value v = pos->getValue(); // Downcast the Value pointer to its actual type - auto prv = dynamic_cast(v.release()); + auto prv = dynamic_cast(v.get()); if (prv == nullptr) throw Exiv2::Error(Exiv2::kerErrorMessage, "Downcast failed"); diff --git a/samples/iotest.cpp b/samples/iotest.cpp index 620ce76f..56277355 100644 --- a/samples/iotest.cpp +++ b/samples/iotest.cpp @@ -81,7 +81,7 @@ int main(int argc, char* const argv[]) } size_t l = 0; if ( !bytes.empty() ) { - int r ; + size_t r ; while ( (r=io->read(bytes.data(),blocksize)) > 0 ) { l += r; output.write(bytes.data(),r) ; @@ -143,7 +143,7 @@ int main(int argc, char* const argv[]) throw Error(Exiv2::kerFileOpenFailed, f2, "w+b", strError()); } - long readCount = 0; + size_t readCount = 0; byte buf[32]; while ((readCount=fileOut1.read(buf, sizeof(buf)))) { if (memIo2.write(buf, readCount) != readCount) { @@ -180,7 +180,7 @@ int WriteReadSeek(BasicIo &io) throw Error(Exiv2::kerDataSourceOpenFailed, io.path(), strError()); } IoCloser closer(io); - if (static_cast(io.write(reinterpret_cast(tester1), static_cast(size1))) != size1) { + if (io.write(reinterpret_cast(tester1), size1) != size1) { std::cerr << ": WRS initial write failed\n"; return 2; } @@ -233,7 +233,7 @@ int WriteReadSeek(BasicIo &io) } io.seek(insert, BasicIo::beg); - if (static_cast(io.write(reinterpret_cast(tester2), static_cast(size2))) != size2) { + if (io.write(reinterpret_cast(tester2), size2) != size2) { std::cerr << ": WRS bad write 1\n"; return 9; } @@ -243,7 +243,7 @@ int WriteReadSeek(BasicIo &io) throw Error(Exiv2::kerDataSourceOpenFailed, io.path(), strError()); } std::memset(buf, -1, sizeof(buf)); - if (static_cast(io.read(buf, sizeof(buf))) != insert + size2) { + if (io.read(buf, sizeof(buf)) != insert + size2) { std::cerr << ": WRS something went wrong\n"; return 10; } diff --git a/samples/largeiptc-test.cpp b/samples/largeiptc-test.cpp index 770ba237..0ba4ea28 100644 --- a/samples/largeiptc-test.cpp +++ b/samples/largeiptc-test.cpp @@ -47,7 +47,7 @@ int main(int argc, char* const argv[]) } Exiv2::DataBuf buf(static_cast(io.size())); std::cout << "Reading " << buf.size() << " bytes from " << data << "\n"; - long readBytes = io.read(buf.data(), buf.size()); + const size_t readBytes = io.read(buf.data(), buf.size()); if (readBytes != buf.size() || io.error() || io.eof()) { throw Exiv2::Error(Exiv2::kerFailedToReadImageData); } diff --git a/samples/tiff-test.cpp b/samples/tiff-test.cpp index dd5e92b5..27f7b09a 100644 --- a/samples/tiff-test.cpp +++ b/samples/tiff-test.cpp @@ -84,7 +84,7 @@ void mini1(const char* path) enforce(wm == wmIntrusive, Exiv2::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[0], static_cast(blob.size())); + ByteOrder bo = ExifParser::decode(exifData, &blob[0], blob.size()); enforce(bo == bigEndian, Exiv2::kerErrorMessage, "decode returned an unexpected value"); print(exifData); } diff --git a/samples/xmpparser-test.cpp b/samples/xmpparser-test.cpp index 6a943d92..985f4c64 100644 --- a/samples/xmpparser-test.cpp +++ b/samples/xmpparser-test.cpp @@ -69,7 +69,7 @@ try { if (file.open("wb") != 0) { throw Exiv2::Error(Exiv2::kerFileOpenFailed, filename, "wb", Exiv2::strError()); } - if (file.write(reinterpret_cast(xmpPacket.data()), static_cast(xmpPacket.size())) == 0) { + if (file.write(reinterpret_cast(xmpPacket.data()), xmpPacket.size()) == 0) { throw Exiv2::Error(Exiv2::kerCallFailed, filename, Exiv2::strError(), "FileIo::write"); } Exiv2::XmpParser::terminate(); diff --git a/src/basicio.cpp b/src/basicio.cpp index 6b1ed0fc..cd2a720c 100644 --- a/src/basicio.cpp +++ b/src/basicio.cpp @@ -87,8 +87,8 @@ namespace { } namespace Exiv2 { - void BasicIo::readOrThrow(byte* buf, long rcount, ErrorCode err) { - const long nread = read(buf, rcount); + void BasicIo::readOrThrow(byte* buf, size_t rcount, ErrorCode err) { + const size_t nread = read(buf, rcount); enforce(nread == rcount, err); enforce(!error(), err); } @@ -336,25 +336,29 @@ namespace Exiv2 { p_->path_ = path; } - long FileIo::write(const byte* data, long wcount) + size_t FileIo::write(const byte* data, size_t wcount) { assert(p_->fp_ != 0); - if (p_->switchMode(Impl::opWrite) != 0) return 0; - return static_cast(std::fwrite(data, 1, wcount, p_->fp_)); + if (p_->switchMode(Impl::opWrite) != 0) + return 0; + return std::fwrite(data, 1, wcount, p_->fp_); } - long FileIo::write(BasicIo& src) + size_t FileIo::write(BasicIo& src) { assert(p_->fp_ != 0); - if (static_cast(this) == &src) return 0; - if (!src.isopen()) return 0; - if (p_->switchMode(Impl::opWrite) != 0) return 0; + if (static_cast(this) == &src) + return 0; + if (!src.isopen()) + return 0; + if (p_->switchMode(Impl::opWrite) != 0) + return 0; byte buf[4096]; - long readCount = 0; - long writeTotal = 0; + size_t readCount = 0; + size_t writeTotal = 0; while ((readCount = src.read(buf, sizeof(buf)))) { - long writeCount = static_cast(std::fwrite(buf, 1, readCount, p_->fp_)); + size_t writeCount = std::fwrite(buf, 1, readCount, p_->fp_); writeTotal += writeCount; if (writeCount != readCount) { // try to reset back to where write stopped @@ -558,27 +562,27 @@ namespace Exiv2 { return rc; } - DataBuf FileIo::read(long rcount) + DataBuf FileIo::read(size_t rcount) { assert(p_->fp_ != 0); if (static_cast(rcount) > size()) throw Error(kerInvalidMalloc); DataBuf buf(rcount); - long readCount = read(buf.data(), buf.size()); - if (readCount < 0) { + size_t readCount = read(buf.data(), buf.size()); + if (readCount == 0) { throw Error(kerInputDataReadFailed); } buf.resize(readCount); return buf; } - long FileIo::read(byte* buf, long rcount) + size_t FileIo::read(byte* buf, size_t rcount) { assert(p_->fp_ != 0); if (p_->switchMode(Impl::opRead) != 0) { return 0; } - return static_cast(std::fread(buf, 1, rcount, p_->fp_)); + return std::fread(buf, 1, rcount, p_->fp_); } int FileIo::getb() @@ -611,25 +615,25 @@ namespace Exiv2 { class MemIo::Impl final{ public: Impl() = default; //!< Default constructor - Impl(const byte* data, long size); //!< Constructor 2 + Impl(const byte* data, size_t size); //!< Constructor 2 // DATA byte* data_{nullptr}; //!< Pointer to the start of the memory area - long idx_{0}; //!< Index into the memory area - long size_{0}; //!< Size of the memory area - long sizeAlloced_{0}; //!< Size of the allocated buffer + size_t idx_{0}; //!< Index into the memory area + size_t size_{0}; //!< Size of the memory area + size_t sizeAlloced_{0}; //!< Size of the allocated buffer bool isMalloced_{false}; //!< Was the buffer allocated? bool eof_{false}; //!< EOF indicator // METHODS - void reserve(long wcount); //!< Reserve memory + void reserve(size_t wcount); //!< Reserve memory // NOT IMPLEMENTED Impl(const Impl& rhs) = delete; //!< Copy constructor Impl& operator=(const Impl& rhs) = delete; //!< Assignment }; // class MemIo::Impl - MemIo::Impl::Impl(const byte* data, long size) : data_(const_cast(data)), size_(size) + MemIo::Impl::Impl(const byte* data, size_t size) : data_(const_cast(data)), size_(size) { } @@ -702,15 +706,15 @@ namespace Exiv2 { size_t size_{0}; }; // class BlockMap - void MemIo::Impl::reserve(long wcount) + void MemIo::Impl::reserve(size_t wcount) { - const long need = wcount + idx_; - long blockSize = 32*1024; // 32768 ` - const long maxBlockSize = 4*1024*1024; + const size_t need = wcount + idx_; + size_t blockSize = 32*1024; // 32768 + const size_t maxBlockSize = 4*1024*1024; if (!isMalloced_) { // Minimum size for 1st block - long size = std::max(blockSize * (1 + need / blockSize), size_); + size_t size = std::max(blockSize * (1 + need / blockSize), size_); auto data = static_cast(std::malloc(size)); if (data == nullptr) { throw Error(kerMallocFailed); @@ -728,7 +732,7 @@ namespace Exiv2 { blockSize = 2*sizeAlloced_ ; if ( blockSize > maxBlockSize ) blockSize = maxBlockSize ; // Allocate in blocks - long want = blockSize * (1 + need / blockSize ); + size_t want = blockSize * (1 + need / blockSize ); data_ = static_cast(std::realloc(data_, want)); if (data_ == nullptr) { throw Error(kerMallocFailed); @@ -744,7 +748,7 @@ namespace Exiv2 { { } - MemIo::MemIo(const byte* data, long size) + MemIo::MemIo(const byte* data, size_t size) : p_(std::make_unique(data, size)) { } @@ -756,7 +760,7 @@ namespace Exiv2 { } } - long MemIo::write(const byte* data, long wcount) + size_t MemIo::write(const byte* data, size_t wcount) { p_->reserve(wcount); assert(p_->isMalloced_); @@ -796,14 +800,14 @@ namespace Exiv2 { if (error() || src.error()) throw Error(kerMemoryTransferFailed, strError()); } - long MemIo::write(BasicIo& src) + size_t MemIo::write(BasicIo& src) { if (static_cast(this) == &src) return 0; if (!src.isopen()) return 0; byte buf[4096]; - long readCount = 0; - long writeTotal = 0; + size_t readCount = 0; + size_t writeTotal = 0; while ((readCount = src.read(buf, sizeof(buf)))) { write(buf, readCount); writeTotal += readCount; @@ -833,7 +837,7 @@ namespace Exiv2 { if (newIdx < 0) return 1; - if (newIdx > p_->size_) { + if (newIdx > static_cast(p_->size_)) { p_->eof_ = true; return 1; } @@ -855,7 +859,7 @@ namespace Exiv2 { long MemIo::tell() const { - return p_->idx_; + return static_cast(p_->idx_); } size_t MemIo::size() const @@ -880,18 +884,18 @@ namespace Exiv2 { return 0; } - DataBuf MemIo::read(long rcount) + DataBuf MemIo::read(size_t rcount) { DataBuf buf(rcount); - long readCount = read(buf.data(), buf.size()); + size_t readCount = read(buf.data(), buf.size()); buf.resize(readCount); return buf; } - long MemIo::read(byte* buf, long rcount) + size_t MemIo::read(byte* buf, size_t rcount) { - const long avail = std::max(p_->size_ - p_->idx_, 0L); - const long allow = std::min(rcount, avail); + const size_t avail = std::max(p_->size_ - p_->idx_, static_cast(0)); + const size_t allow = std::min(rcount, avail); if (allow > 0) { std::memcpy(buf, &p_->data_[p_->idx_], allow); } @@ -1075,11 +1079,11 @@ namespace Exiv2 { size_t blockSize_; //!< Size of the block memory. BlockMap* blocksMap_; //!< An array contains all blocksMap size_t size_; //!< The file size - long idx_; //!< Index into the memory area + size_t idx_; //!< Index into the memory area bool isMalloced_; //!< Was the blocksMap_ allocated? bool eof_; //!< EOF indicator Protocol protocol_; //!< the protocol of url - uint32_t totalRead_; //!< bytes requested from host + size_t totalRead_; //!< bytes requested from host // METHODS /*! @@ -1229,12 +1233,12 @@ namespace Exiv2 { return 0; } - long RemoteIo::write(const byte* /* unused data*/, long /* unused wcount*/) + size_t RemoteIo::write(const byte* /* unused data*/, size_t /* unused wcount*/) { return 0; // means failure } - long RemoteIo::write(BasicIo& src) + size_t RemoteIo::write(BasicIo& src) { assert(p_->isMalloced_); if (!src.isopen()) return 0; @@ -1258,7 +1262,7 @@ namespace Exiv2 { while (blockIndex < nBlocks && !src.eof() && !findDiff) { size_t blockSize = p_->blocksMap_[blockIndex].getSize(); bool isFakeData = p_->blocksMap_[blockIndex].isKnown(); // fake data - size_t readCount = static_cast(src.read(buf.data(), static_cast(blockSize))); + size_t readCount = src.read(buf.data(), blockSize); byte* blockData = p_->blocksMap_[blockIndex].getData(); for (size_t i = 0; (i < readCount) && (i < blockSize) && !findDiff; i++) { if ((!isFakeData && buf[i] != blockData[i]) || (isFakeData && buf[i] != 0)) { @@ -1280,7 +1284,7 @@ namespace Exiv2 { findDiff = true; } else { bool isFakeData = p_->blocksMap_[blockIndex].isKnown(); // fake data - size_t readCount = src.read(buf.data(), static_cast(blockSize)); + size_t readCount = src.read(buf.data(), blockSize); byte* blockData = p_->blocksMap_[blockIndex].getData(); for (size_t i = 0; (i < readCount) && (i < blockSize) && !findDiff; i++) { if ((!isFakeData && buf[readCount - i - 1] != blockData[blockSize - i - 1]) || (isFakeData && buf[readCount - i - 1] != 0)) { @@ -1298,9 +1302,9 @@ namespace Exiv2 { auto data = static_cast(std::malloc(dataSize)); src.seek(left, BasicIo::beg); src.read(data, dataSize); - p_->writeRemote(data, static_cast(dataSize), static_cast(left), - static_cast(p_->size_ - right)); - if (data) std::free(data); + p_->writeRemote(data, dataSize, static_cast(left), static_cast(p_->size_ - right)); + if (data) + std::free(data); } return static_cast(src.size()); } @@ -1310,24 +1314,25 @@ namespace Exiv2 { return 0; } - DataBuf RemoteIo::read(long rcount) + DataBuf RemoteIo::read(size_t rcount) { DataBuf buf(rcount); - long readCount = read(buf.data(), buf.size()); - if (readCount < 0) { + size_t readCount = read(buf.data(), buf.size()); + if (readCount == 0) { throw Error(kerInputDataReadFailed); } buf.resize(readCount); return buf; } - long RemoteIo::read(byte* buf, long rcount) + size_t RemoteIo::read(byte* buf, size_t rcount) { assert(p_->isMalloced_); - if (p_->eof_) return 0; + if (p_->eof_) + return 0; p_->totalRead_ += rcount; - size_t allow = std::min(rcount, (long)( p_->size_ - p_->idx_)); + size_t allow = std::min(rcount, ( p_->size_ - p_->idx_)); size_t lowBlock = p_->idx_ /p_->blockSize_; size_t highBlock = (p_->idx_ + allow)/p_->blockSize_; @@ -1354,16 +1359,16 @@ namespace Exiv2 { std::free(fakeData); - p_->idx_ += static_cast(totalRead); - p_->eof_ = (p_->idx_ == static_cast(p_->size_)); + p_->idx_ += totalRead; + p_->eof_ = (p_->idx_ == p_->size_); - return static_cast(totalRead); + return totalRead; } int RemoteIo::getb() { assert(p_->isMalloced_); - if (p_->idx_ == static_cast(p_->size_)) { + if (p_->idx_ == p_->size_) { p_->eof_ = true; return EOF; } @@ -1398,10 +1403,10 @@ namespace Exiv2 { // #1198. Don't return 1 when asked to seek past EOF. Stay calm and set eof_ // if (newIdx < 0 || newIdx > (long) p_->size_) return 1; - p_->idx_ = static_cast(newIdx); - p_->eof_ = newIdx > static_cast(p_->size_); - if (p_->idx_ > static_cast(p_->size_)) - p_->idx_ = static_cast(p_->size_); + p_->idx_ = static_cast(newIdx); + p_->eof_ = newIdx > static_cast(p_->size_); + if (p_->idx_ > p_->size_) + p_->idx_ = p_->size_; return 0; } @@ -1435,7 +1440,7 @@ namespace Exiv2 { long RemoteIo::tell() const { - return p_->idx_; + return static_cast(p_->idx_); } size_t RemoteIo::size() const @@ -1808,7 +1813,7 @@ namespace Exiv2 { curl_easy_cleanup(curl_); } - long CurlIo::write(const byte* data, long wcount) + size_t CurlIo::write(const byte* data, size_t wcount) { if (p_->protocol_ == pHttp || p_->protocol_ == pHttps) { return RemoteIo::write(data, wcount); @@ -1816,7 +1821,7 @@ namespace Exiv2 { throw Error(kerErrorMessage, "doesnt support write for this protocol."); } - long CurlIo::write(BasicIo& src) + size_t CurlIo::write(BasicIo& src) { if (p_->protocol_ == pHttp || p_->protocol_ == pHttps) { return RemoteIo::write(src); @@ -1845,14 +1850,14 @@ namespace Exiv2 { throw Error(kerCallFailed, path, strError(), "::stat"); } DataBuf buf(st.st_size); - long len = file.read(buf.data(), buf.size()); + const size_t len = file.read(buf.data(), buf.size()); if (len != buf.size()) { throw Error(kerCallFailed, path, strError(), "FileIo::read"); } return buf; } - long writeFile(const DataBuf& buf, const std::string& path) + size_t writeFile(const DataBuf& buf, const std::string& path) { FileIo file(path); if (file.open("wb") != 0) { diff --git a/src/bmffimage.cpp b/src/bmffimage.cpp index c2d6c8ff..41fb8d82 100644 --- a/src/bmffimage.cpp +++ b/src/bmffimage.cpp @@ -237,24 +237,24 @@ namespace Exiv2 // read data in box and restore file position long restore = io_->tell(); enforce(box_length >= hdrsize, Exiv2::kerCorruptedMetadata); - enforce(box_length - hdrsize <= static_cast(pbox_end - restore), Exiv2::kerCorruptedMetadata); + enforce(box_length - hdrsize <= static_cast(pbox_end - restore), Exiv2::kerCorruptedMetadata); - const long buffer_size = static_cast(box_length - hdrsize); + const size_t buffer_size = static_cast(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 + buffer_size; + return restore + static_cast(buffer_size); } DataBuf data(buffer_size); - const long box_end = restore + data.size(); + const long box_end = restore + static_cast(data.size()); io_->read(data.data(), data.size()); io_->seek(restore, BasicIo::beg); - long skip = 0; // read position in data.pData_ + size_t skip = 0; // read position in data.pData_ uint8_t version = 0; uint32_t flags = 0; @@ -366,7 +366,7 @@ namespace Exiv2 #else skip++; #endif - enforce(data.size() - skip >= (version < 2 ? 2 : 4), Exiv2::kerCorruptedMetadata); + enforce(data.size() - skip >= (version < 2u ? 2u : 4u), Exiv2::kerCorruptedMetadata); uint32_t itemCount = version < 2 ? data.read_uint16(skip, endian_) : data.read_uint32(skip, endian_); skip += version < 2 ? 2 : 4; @@ -376,11 +376,11 @@ namespace Exiv2 out << std::endl; bLF = false; } - long step = static_cast((box_length - 16) / itemCount); // length of data per item. - long base = skip; + size_t step = (static_cast(box_length) - 16) / itemCount; // length of data per item. + 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 > 2 ? 4 : 2), Exiv2::kerCorruptedMetadata); + enforce(data.size() - skip >= (version > 2u ? 4u : 2u), Exiv2::kerCorruptedMetadata); enforce(data.size() - skip >= step, Exiv2::kerCorruptedMetadata); uint32_t ID = version > 2 ? data.read_uint32(skip, endian_) : data.read_uint16(skip, endian_); @@ -423,8 +423,7 @@ namespace Exiv2 // 12.1.5.2 case TAG_colr: { - if (data.size() >= - static_cast(skip + 4 + 8)) { // .____.HLino..__mntrR 2 0 0 0 0 12 72 76 105 110 111 2 16 ... + if (data.size() >= (skip + 4 + 8)) { // .____.HLino..__mntrR 2 0 0 0 0 12 72 76 105 110 111 2 16 ... // https://www.ics.uci.edu/~dan/class/267/papers/jpeg2000.pdf uint8_t meth = data.read_uint8(skip+0); uint8_t prec = data.read_uint8(skip+1); @@ -518,26 +517,26 @@ namespace Exiv2 { enforce(start <= io_->size(), kerCorruptedMetadata); enforce(length <= io_->size() - start, kerCorruptedMetadata); - enforce(start <= static_cast(std::numeric_limits::max()), kerCorruptedMetadata); - enforce(length <= static_cast(std::numeric_limits::max()), kerCorruptedMetadata); + enforce(start <= std::numeric_limits::max(), kerCorruptedMetadata); + enforce(length <= std::numeric_limits::max(), kerCorruptedMetadata); // read and parse exif data long restore = io_->tell(); - DataBuf exif(static_cast(length)); + DataBuf exif(static_cast(length)); 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; - for ( long i = 0 ; i < exif.size() -8 && punt==eof ; i+=2) { + 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 = i; + punt = static_cast(i); } if ( punt != eof ) { - Internal::TiffParserWorker::decode(exifData(), iptcData(), xmpData(), - exif.c_data(punt), exif.size()-punt, root_tag, - Internal::TiffMapping::findDecoder); + Internal::TiffParserWorker::decode(exifData(), iptcData(), xmpData(), exif.c_data(punt), + static_cast(exif.size()-punt), root_tag, + Internal::TiffMapping::findDecoder); } } io_->seek(restore,BasicIo::beg); @@ -547,9 +546,9 @@ namespace Exiv2 { if (length > 8) { enforce(length - 8 <= io_->size() - io_->tell(), kerCorruptedMetadata); - enforce(length - 8 <= static_cast(std::numeric_limits::max()), kerCorruptedMetadata); - DataBuf data(static_cast(length - 8)); - long bufRead = io_->read(data.data(), data.size()); + enforce(length - 8 <= std::numeric_limits::max(), kerCorruptedMetadata); + DataBuf data(static_cast(length) - 8); + const size_t bufRead = io_->read(data.data(), data.size()); if (io_->error()) throw Error(kerFailedToReadImageData); @@ -557,7 +556,7 @@ namespace Exiv2 throw Error(kerInputDataReadFailed); Internal::TiffParserWorker::decode(exifData(), iptcData(), xmpData(), - data.c_data(), data.size(), root_tag, + data.c_data(), static_cast(data.size()), root_tag, Internal::TiffMapping::findDecoder); } } @@ -569,13 +568,13 @@ namespace Exiv2 enforce(length <= io_->size() - start, kerCorruptedMetadata); long restore = io_->tell() ; - enforce(start <= static_cast(std::numeric_limits::max()), kerCorruptedMetadata); + enforce(start <= std::numeric_limits::max(), kerCorruptedMetadata); io_->seek(static_cast(start),BasicIo::beg); - enforce(length < static_cast(std::numeric_limits::max()), kerCorruptedMetadata); - DataBuf xmp(static_cast(length+1)); + enforce(length < std::numeric_limits::max(), kerCorruptedMetadata); + DataBuf xmp(static_cast(length+1)); xmp.write_uint8(static_cast(length), 0); // ensure xmp is null terminated! - if ( io_->read(xmp.data(), static_cast(length)) != static_cast(length) ) + if ( io_->read(xmp.data(), static_cast(length)) != length ) throw Error(kerInputDataReadFailed); if ( io_->error() ) throw Error(kerFailedToReadImageData); @@ -589,14 +588,15 @@ namespace Exiv2 } } + /// \todo instead of passing the last 4 parameters, pass just one and build the different offsets inside void BmffImage::parseCr3Preview(DataBuf &data, std::ostream& out, bool bTrace, uint8_t version, - uint32_t width_offset, - uint32_t height_offset, - uint32_t size_offset, - uint32_t relative_position) + 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(); @@ -604,7 +604,7 @@ namespace Exiv2 here <= std::numeric_limits::max() - static_cast(relative_position), kerCorruptedMetadata); NativePreview nativePreview; - nativePreview.position_ = here + relative_position; + nativePreview.position_ = here + static_cast(relative_position); nativePreview.width_ = data.read_uint16(width_offset, endian_); nativePreview.height_ = data.read_uint16(height_offset, endian_); nativePreview.size_ = data.read_uint32(size_offset, endian_); diff --git a/src/casiomn_int.cpp b/src/casiomn_int.cpp index db1d7957..144cb2c4 100644 --- a/src/casiomn_int.cpp +++ b/src/casiomn_int.cpp @@ -225,14 +225,15 @@ namespace Exiv2 { { // format is: "YYMM#00#00DDHH#00#00MM#00#00#00#00" or "YYMM#00#00DDHH#00#00MMSS#00#00#00" std::vector numbers; - for(long i=0; i(l)); - }; - }; + } + } + if(numbers.size()>=10) { //year @@ -544,14 +545,15 @@ namespace Exiv2 { { // format is: "YYMM#00#00DDHH#00#00MM#00#00#00#00" std::vector numbers; - for(long i=0; i(value.toInt64(i)); if(l!=0) { - numbers.push_back(static_cast(l)); - }; - }; + numbers.push_back(l); + } + } + if(numbers.size()>=10) { //year diff --git a/src/convert.cpp b/src/convert.cpp index d7348701..28af594a 100644 --- a/src/convert.cpp +++ b/src/convert.cpp @@ -547,7 +547,7 @@ namespace Exiv2 { auto pos = exifData_->findKey(ExifKey(from)); if (pos == exifData_->end()) return; if (!prepareXmpTarget(to)) return; - for (long i = 0; i < pos->count(); ++i) { + for (size_t i = 0; i < pos->count(); ++i) { std::string value = pos->toString(i); if (!pos->value().ok()) { #ifndef SUPPRESS_WARNINGS @@ -695,7 +695,7 @@ namespace Exiv2 { if (pos == exifData_->end()) return; if (!prepareXmpTarget(to)) return; std::ostringstream value; - for (long i = 0; i < pos->count(); ++i) { + for (size_t i = 0; i < pos->count(); ++i) { value << static_cast(pos->toInt64(i)); } (*xmpData_)[to] = value.str(); @@ -708,7 +708,7 @@ namespace Exiv2 { if (pos == exifData_->end()) return; if (!prepareXmpTarget(to)) return; std::ostringstream value; - for (long i = 0; i < pos->count(); ++i) { + for (size_t i = 0; i < pos->count(); ++i) { if (i > 0) value << '.'; value << pos->toInt64(i); } @@ -826,7 +826,7 @@ namespace Exiv2 { auto pos = xmpData_->findKey(XmpKey(from)); if (pos == xmpData_->end()) return; std::ostringstream array; - for (long i = 0; i < pos->count(); ++i) { + for (size_t i = 0; i < pos->count(); ++i) { std::string value = pos->toString(i); if (!pos->value().ok()) { #ifndef SUPPRESS_WARNINGS @@ -835,10 +835,12 @@ namespace Exiv2 { return; } array << value; - if (i != pos->count() - 1) array << " "; + if (i != pos->count() - 1) + array << " "; } (*exifData_)[to] = array.str(); - if (erase_) xmpData_->erase(pos); + if (erase_) + xmpData_->erase(pos); } void Converter::cnvXmpDate(const char* from, const char* to) @@ -859,9 +861,9 @@ namespace Exiv2 { SXMPUtils::ConvertToDate(value, &datetime); char buf[30]; if (std::string(to) != "Exif.GPSInfo.GPSTimeStamp") { - + SXMPUtils::ConvertToLocalTime(&datetime); - + snprintf(buf, sizeof(buf), "%4d:%02d:%02d %02d:%02d:%02d", static_cast(datetime.year), static_cast(datetime.month), @@ -871,7 +873,7 @@ namespace Exiv2 { static_cast(datetime.second)); buf[sizeof(buf) - 1] = 0; (*exifData_)[to] = buf; - + if (datetime.nanoSecond) { const char* subsecTag = nullptr; if (std::string(to) == "Exif.Image.DateTime") { @@ -890,9 +892,9 @@ namespace Exiv2 { } } else { // "Exif.GPSInfo.GPSTimeStamp" - + // Ignore the time zone, assuming the time is in UTC as it should be - + URational rhour(datetime.hour, 1); URational rmin(datetime.minute, 1); URational rsec(datetime.second, 1); @@ -906,11 +908,11 @@ namespace Exiv2 { rsec.second = 1000000000; rsec.first = datetime.nanoSecond; } - + std::ostringstream array; array << rhour << " " << rmin << " " << rsec; (*exifData_)[to] = array.str(); - + prepareExifTarget("Exif.GPSInfo.GPSDateStamp", true); snprintf(buf, sizeof(buf), "%4d:%02d:%02d", static_cast(datetime.year), @@ -1153,10 +1155,10 @@ namespace Exiv2 { return; } - int count = pos->count(); + size_t count = pos->count(); bool added = false; - for (int i = 0; i < count; ++i) { - std::string value = pos->toString(i); + for (size_t i = 0; i < count; ++i) { + std::string value = pos->toString(static_cast(i)); if (!pos->value().ok()) { #ifndef SUPPRESS_WARNINGS EXV_WARNING << "Failed to convert " << from << " to " << to << "\n"; @@ -1193,7 +1195,7 @@ namespace Exiv2 { if (pos == exifData_->end()) continue; DataBuf data(pos->size()); pos->copy(data.data(), littleEndian /* FIXME ? */); - MD5Update ( &context, data.c_data(), data.size()); + MD5Update ( &context, data.c_data(), static_cast(data.size())); } } MD5Final(digest, &context); diff --git a/src/crwimage.cpp b/src/crwimage.cpp index 92b16700..bde8c6b0 100644 --- a/src/crwimage.cpp +++ b/src/crwimage.cpp @@ -101,7 +101,7 @@ namespace Exiv2 { throw Error(kerNotACrwImage); } clearMetadata(); - DataBuf file(static_cast(io().size())); + DataBuf file(io().size()); io_->read(file.data(), file.size()); CrwParser::decode(this, io_->mmap(), static_cast(io_->size())); @@ -120,7 +120,7 @@ namespace Exiv2 { // Ensure that this is the correct image type if (isCrwType(*io_, false)) { // Read the image into a memory buffer - buf.alloc(static_cast(io_->size())); + buf.alloc(io_->size()); io_->read(buf.data(), buf.size()); if (io_->error() || io_->eof()) { buf.reset(); @@ -129,7 +129,7 @@ namespace Exiv2 { } Blob blob; - CrwParser::encode(blob, buf.c_data(), buf.size(), this); + CrwParser::encode(blob, buf.c_data(), static_cast(buf.size()), this); // Write new buffer to file auto tempIo = std::make_unique(); diff --git a/src/crwimage_int.cpp b/src/crwimage_int.cpp index 6cb86baf..d9ce1ce8 100644 --- a/src/crwimage_int.cpp +++ b/src/crwimage_int.cpp @@ -543,7 +543,7 @@ namespace Exiv2 { { storage_ = std::move(buf); pData_ = storage_.c_data(); - size_ = storage_.size(); + size_ = static_cast(storage_.size()); if (size_ > 8 && dataLocation() == directoryData) { tag_ &= 0x3fff; } @@ -1082,7 +1082,7 @@ namespace Exiv2 { } assert(ifdId != ifdIdNotSet); DataBuf buf = packIfdId(image.exifData(), ifdId, pHead->byteOrder()); - if (buf.size() == 0) { + if (buf.empty()) { // Try the undecoded tag encodeBasic(image, pCrwMapping, pHead); } diff --git a/src/epsimage.cpp b/src/epsimage.cpp index 386508b8..8a2dc954 100644 --- a/src/epsimage.cpp +++ b/src/epsimage.cpp @@ -107,8 +107,9 @@ namespace { //! Write data into temp file, taking care of errors void writeTemp(BasicIo& tempIo, const byte* data, size_t size) { - if (size == 0) return; - if (tempIo.write(data, static_cast(size)) != static_cast(size)) { + if (size == 0) + return; + if (tempIo.write(data, size) != size) { #ifndef SUPPRESS_WARNINGS EXV_WARNING << "Failed to write to temporary file.\n"; #endif @@ -1079,7 +1080,7 @@ namespace Exiv2 EXV_DEBUG << "Exiv2::EpsImage:: Creating blank EPS image\n"; #endif IoCloser closer(*io_); - if (io_->write(reinterpret_cast(epsBlank.data()), static_cast(epsBlank.size())) != static_cast(epsBlank.size())) { + if (io_->write(reinterpret_cast(epsBlank.data()), epsBlank.size()) != epsBlank.size()) { #ifndef SUPPRESS_WARNINGS EXV_WARNING << "Failed to write blank EPS image.\n"; #endif @@ -1157,10 +1158,10 @@ namespace Exiv2 bool isEpsType(BasicIo& iIo, bool advance) { // read as many bytes as needed for the longest (DOS) EPS signature - long bufSize = static_cast(dosEpsSignature.size()); + size_t bufSize = dosEpsSignature.size(); for (auto&& i : epsFirstLine) { - if (bufSize < static_cast(i.size())) { - bufSize = static_cast(i.size()); + if (bufSize < i.size()) { + bufSize = i.size(); } } const long restore = iIo.tell(); // save diff --git a/src/exif.cpp b/src/exif.cpp index 64d14134..8df2f6b6 100644 --- a/src/exif.cpp +++ b/src/exif.cpp @@ -315,7 +315,7 @@ namespace Exiv2 { return value_->read(value); } - int Exifdatum::setDataArea(const byte* buf, long len) + int Exifdatum::setDataArea(const byte* buf, size_t len) { return value_.get() == nullptr ? -1 : value_->setDataArea(buf, len); } @@ -382,17 +382,17 @@ namespace Exiv2 { long Exifdatum::typeSize() const { - return TypeInfo::typeSize(typeId()); + return static_cast(TypeInfo::typeSize(typeId())); } - long Exifdatum::count() const + size_t Exifdatum::count() const { return value_.get() == nullptr ? 0 : value_->count(); } long Exifdatum::size() const { - return value_.get() == nullptr ? 0 : value_->size(); + return value_.get() == nullptr ? 0 : static_cast(value_->size()); } std::string Exifdatum::toString() const @@ -425,7 +425,7 @@ namespace Exiv2 { return value_.get() == nullptr ? nullptr : value_->clone(); } - long Exifdatum::sizeDataArea() const + size_t Exifdatum::sizeDataArea() const { return value_.get() == nullptr ? 0 : value_->sizeDataArea(); } @@ -448,7 +448,7 @@ namespace Exiv2 { return thumbnail->copy(exifData_); } - long ExifThumbC::writeFile(const std::string& path) const + size_t ExifThumbC::writeFile(const std::string& path) const { auto thumbnail = Thumbnail::create(exifData_); if (!thumbnail.get()) @@ -456,7 +456,7 @@ namespace Exiv2 { std::string name = path + thumbnail->extension(); DataBuf buf(thumbnail->copy(exifData_)); - if (buf.size() == 0) + if (buf.empty()) return 0; return Exiv2::writeFile(buf, name); @@ -483,24 +483,13 @@ namespace Exiv2 { { } - void ExifThumb::setJpegThumbnail( - const std::string& path, - URational xres, - URational yres, - uint16_t unit - ) + void ExifThumb::setJpegThumbnail(const std::string& path, URational xres, URational yres, uint16_t unit) { DataBuf thumb = readFile(path); // may throw setJpegThumbnail(thumb.c_data(), thumb.size(), xres, yres, unit); } - void ExifThumb::setJpegThumbnail( - const byte* buf, - long size, - URational xres, - URational yres, - uint16_t unit - ) + void ExifThumb::setJpegThumbnail(const byte* buf, size_t size, URational xres, URational yres, uint16_t unit) { setJpegThumbnail(buf, size); exifData_["Exif.Thumbnail.XResolution"] = xres; @@ -514,7 +503,7 @@ namespace Exiv2 { setJpegThumbnail(thumb.c_data(), thumb.size()); } - void ExifThumb::setJpegThumbnail(const byte* buf, long size) + void ExifThumb::setJpegThumbnail(const byte* buf, size_t size) { exifData_["Exif.Thumbnail.Compression"] = uint16_t(6); Exifdatum& format = exifData_["Exif.Thumbnail.JPEGInterchangeFormat"]; @@ -587,19 +576,11 @@ namespace Exiv2 { return exifMetadata_.erase(pos); } - ByteOrder ExifParser::decode( - ExifData& exifData, - const byte* pData, - uint32_t size - ) + ByteOrder ExifParser::decode(ExifData& exifData, const byte* pData, size_t size) { IptcData iptcData; XmpData xmpData; - ByteOrder bo = TiffParser::decode(exifData, - iptcData, - xmpData, - pData, - size); + ByteOrder bo = TiffParser::decode(exifData, iptcData, xmpData, pData, size); #ifndef SUPPRESS_WARNINGS if (!iptcData.empty()) { EXV_WARNING << "Ignoring IPTC information encoded in the Exif data.\n"; @@ -609,7 +590,7 @@ namespace Exiv2 { } #endif return bo; - } // ExifParser::decode + } //! @cond IGNORE enum Ptt { pttLen, pttTag, pttIfd }; @@ -619,13 +600,8 @@ namespace Exiv2 { }; //! @endcond - WriteMethod ExifParser::encode( - Blob& blob, - const byte* pData, - uint32_t size, - ByteOrder byteOrder, - const ExifData& exifData - ) + WriteMethod ExifParser::encode(Blob& blob, const byte* pData, size_t size, ByteOrder byteOrder, + const ExifData& exifData) { ExifData ed = exifData; @@ -697,8 +673,8 @@ namespace Exiv2 { // Encode and check if the result fits into a JPEG Exif APP1 segment MemIo mio1; TiffHeader header(byteOrder, 0x00000008, false); - WriteMethod wm = TiffParserWorker::encode(mio1, pData, size, ed, emptyIptc, emptyXmp, Tag::root, - TiffMapping::findEncoder, &header, nullptr); + WriteMethod wm = TiffParserWorker::encode(mio1, pData, static_cast(size), ed, emptyIptc, emptyXmp, + Tag::root, TiffMapping::findEncoder, &header, nullptr); if (mio1.size() <= 65527) { append(blob, mio1.mmap(), static_cast(mio1.size())); return wm; @@ -795,8 +771,8 @@ namespace Exiv2 { // Encode the remaining Exif tags again, don't care if it fits this time MemIo mio2; - wm = TiffParserWorker::encode(mio2, pData, size, ed, emptyIptc, emptyXmp, Tag::root, TiffMapping::findEncoder, - &header, nullptr); + wm = TiffParserWorker::encode(mio2, pData, static_cast(size), ed, emptyIptc, emptyXmp, Tag::root, + TiffMapping::findEncoder, &header, nullptr); append(blob, mio2.mmap(), static_cast(mio2.size())); #ifdef EXIV2_DEBUG_MESSAGES if (wm == wmIntrusive) { @@ -868,7 +844,7 @@ namespace { Exiv2::IptcData emptyIptc; Exiv2::XmpData emptyXmp; Exiv2::TiffParser::encode(io, nullptr, 0, Exiv2::littleEndian, thumb, emptyIptc, emptyXmp); - return io.read(static_cast(io.size())); + return io.read(io.size()); } const char* JpegThumbnail::mimeType() const @@ -892,7 +868,7 @@ namespace { int64_t sumToLong(const Exiv2::Exifdatum& md) { int64_t sum = 0; - for (long i = 0; i < md.count(); ++i) { + for (size_t i = 0; i < md.count(); ++i) { sum += md.toInt64(i); } return sum; diff --git a/src/image.cpp b/src/image.cpp index c7022951..fd9a7cbc 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -415,7 +415,7 @@ namespace Exiv2 { if ( bOffsetIsPointer ) { // read into buffer const long restore = io.tell(); // save io.seekOrThrow(offset, BasicIo::beg, kerCorruptedMetadata); // position - io.readOrThrow(buf.data(), static_cast(count_x_size), kerCorruptedMetadata); // read + io.readOrThrow(buf.data(), count_x_size, kerCorruptedMetadata); // read io.seekOrThrow(restore, BasicIo::beg, kerCorruptedMetadata); // restore } @@ -672,7 +672,7 @@ namespace Exiv2 { if (iccProfile.size() < static_cast(sizeof(long))) { throw Error(kerInvalidIccProfile); } - const long size = iccProfile.read_uint32(0, bigEndian); + const size_t size = iccProfile.read_uint32(0, bigEndian); if (size != iccProfile.size()) { throw Error(kerInvalidIccProfile); } @@ -826,7 +826,7 @@ namespace Exiv2 { return getType(fileIo); } - ImageType ImageFactory::getType(const byte* data, long size) + ImageType ImageFactory::getType(const byte* data, size_t size) { MemIo memIo(data, size); return getType(memIo); @@ -875,7 +875,7 @@ namespace Exiv2 { return image; } - Image::UniquePtr ImageFactory::open(const byte* data, long size) + Image::UniquePtr ImageFactory::open(const byte* data, size_t size) { auto io = std::make_unique(data, size); auto image = open(std::move(io)); // may throw @@ -937,7 +937,7 @@ namespace Exiv2 { // ***************************************************************************** // template, inline and free functions - void append(Blob& blob, const byte* buf, uint32_t len) + void append(Blob& blob, const byte* buf, size_t len) { if (len != 0) { assert(buf != 0); diff --git a/src/iptc.cpp b/src/iptc.cpp index b3874a46..d3f4dfdb 100644 --- a/src/iptc.cpp +++ b/src/iptc.cpp @@ -158,17 +158,17 @@ namespace Exiv2 { long Iptcdatum::typeSize() const { - return TypeInfo::typeSize(typeId()); + return static_cast(TypeInfo::typeSize(typeId())); } - long Iptcdatum::count() const + size_t Iptcdatum::count() const { return value_.get() == nullptr ? 0 : value_->count(); } long Iptcdatum::size() const { - return value_.get() == nullptr ? 0 : value_->size(); + return value_.get() == nullptr ? 0 : static_cast(value_->size()); } std::string Iptcdatum::toString() const @@ -505,7 +505,9 @@ namespace Exiv2 { DataBuf IptcParser::encode(const IptcData& iptcData) { - /// \todo if iptcData.size() == 0 return early + if (iptcData.empty()) + return {}; + DataBuf buf(iptcData.size()); byte *pWrite = buf.data(); diff --git a/src/jp2image.cpp b/src/jp2image.cpp index 1778f634..060b01f7 100644 --- a/src/jp2image.cpp +++ b/src/jp2image.cpp @@ -35,6 +35,7 @@ #include "safe_op.hpp" // + standard includes +#include #include #include #include @@ -283,9 +284,9 @@ static void boxes_check(size_t b,size_t m) if (data_length > io_->size() - io_->tell()) { throw Error(kerCorruptedMetadata); } - DataBuf data(static_cast(data_length)); + DataBuf data(data_length); io_->read(data.data(), data.size()); - const long iccLength = data.read_uint32(pad, bigEndian); + const size_t iccLength = data.read_uint32(pad, bigEndian); // subtracting pad from data.size() is safe: // data.size() is at least 8 and pad = 3 if (iccLength > data.size() - pad) { @@ -338,7 +339,7 @@ static void boxes_check(size_t b,size_t m) if (io_->read(reinterpret_cast(&uuid), sizeof(uuid)) == sizeof(uuid)) { DataBuf rawData; - long bufRead; + size_t bufRead; bool bIsExif = memcmp(uuid.uuid, kJp2UuidExif, sizeof(uuid))==0; bool bIsIPTC = memcmp(uuid.uuid, kJp2UuidIptc, sizeof(uuid))==0; bool bIsXMP = memcmp(uuid.uuid, kJp2UuidXmp , sizeof(uuid))==0; @@ -362,12 +363,11 @@ static void boxes_check(size_t b,size_t m) long pos = (a == b && (a=='I' || a=='M')) ? 0 : -1; // #1242 Forgive having Exif\0\0 in rawData.pData_ - const byte exifHeader[] = { 0x45, 0x78, 0x69, 0x66, 0x00, 0x00 }; - for (long i = 0; pos < 0 && i < rawData.size() - static_cast(sizeof(exifHeader)); - i++) { - if (rawData.cmpBytes(i, exifHeader, sizeof(exifHeader)) == 0) + std::array exifHeader { 0x45, 0x78, 0x69, 0x66, 0x00, 0x00 }; + for (size_t i = 0; pos < 0 && i < (rawData.size() - exifHeader.size()); i++) { + if (rawData.cmpBytes(i, exifHeader.data(), exifHeader.size()) == 0) { - pos = i+sizeof(exifHeader); + pos = static_cast(i+sizeof(exifHeader)); #ifndef SUPPRESS_WARNINGS EXV_WARNING << "Reading non-standard UUID-EXIF_bad box in " << io_->path() << std::endl; #endif @@ -409,7 +409,7 @@ static void boxes_check(size_t b,size_t m) if (io_->error()) throw Error(kerFailedToReadImageData); if (bufRead != rawData.size()) throw Error(kerInputDataReadFailed); - if (IptcParser::decode(iptcData_, rawData.c_data(), rawData.size())) + if (IptcParser::decode(iptcData_, rawData.c_data(), static_cast(rawData.size()))) { #ifndef SUPPRESS_WARNINGS EXV_WARNING << "Failed to decode IPTC metadata." << std::endl; @@ -530,15 +530,14 @@ static void boxes_check(size_t b,size_t m) DataBuf data(subBox.length - sizeof(box)); io_->read(data.data(), data.size()); if (bPrint) { - out << Internal::stringFormat("%8ld | %8ld | sub:", static_cast(address), - static_cast(subBox.length)) + out << Internal::stringFormat("%8ld | %8ld | sub:", address, subBox.length) << toAscii(subBox.type) << " | " - << Internal::binaryToString(makeSlice(data, 0, std::min(30L, data.size()))); + << Internal::binaryToString(makeSlice(data, 0, std::min(static_cast(30), data.size()))); bLF = true; } if (subBox.type == kJp2BoxTypeColorHeader) { - long pad = 3; // don't know why there are 3 padding bytes + 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, kerCorruptedMetadata); @@ -548,7 +547,8 @@ static void boxes_check(size_t b,size_t m) for (int i = 0; i < 3; i++) out << " " << static_cast(data.read_uint8(i)); } - long iccLength = data.read_uint32(pad, bigEndian); + + const size_t iccLength = data.read_uint32(pad, bigEndian); if (bPrint) { out << " | iccLength:" << iccLength; } @@ -583,7 +583,7 @@ static void boxes_check(size_t b,size_t m) DataBuf rawData; enforce(box.length >= sizeof(uuid) + sizeof(box), kerCorruptedMetadata); rawData.alloc(box.length - sizeof(uuid) - sizeof(box)); - long bufRead = io_->read(rawData.data(), rawData.size()); + const size_t bufRead = io_->read(rawData.data(), rawData.size()); if (io_->error()) throw Error(kerFailedToReadImageData); if (bufRead != rawData.size()) @@ -655,10 +655,10 @@ static void boxes_check(size_t b,size_t m) DataBuf output(boxBuf.size() + iccProfile_.size() + 100); // allocate sufficient space long outlen = sizeof(Jp2BoxHeader) ; // now many bytes have we written to output? long inlen = sizeof(Jp2BoxHeader) ; // how many bytes have we read from boxBuf? - enforce(sizeof(Jp2BoxHeader) <= static_cast(output.size()), Exiv2::kerCorruptedMetadata); + enforce(sizeof(Jp2BoxHeader) <= output.size(), Exiv2::kerCorruptedMetadata); auto pBox = reinterpret_cast(boxBuf.c_data()); uint32_t length = getLong(reinterpret_cast(&pBox->length), bigEndian); - enforce(length <= static_cast(output.size()), Exiv2::kerCorruptedMetadata); + enforce(length <= output.size(), Exiv2::kerCorruptedMetadata); uint32_t count = sizeof (Jp2BoxHeader); auto p = boxBuf.c_str(); bool bWroteColor = false ; @@ -694,7 +694,7 @@ static void boxes_check(size_t b,size_t m) const char* pad = "\x01\x00\x00\x00\x00\x00\x10\x00\x00\x05\x1cuuid"; uint32_t psize = 15; newlen = sizeof(newBox) + psize ; - enforce(newlen <= static_cast(output.size() - outlen), Exiv2::kerCorruptedMetadata); + enforce(newlen <= output.size() - outlen, Exiv2::kerCorruptedMetadata); ul2Data(reinterpret_cast(&newBox.length), psize, bigEndian); ul2Data(reinterpret_cast(&newBox.type), newBox.type, bigEndian); output.copyBytes(outlen ,&newBox ,sizeof(newBox)); @@ -702,7 +702,7 @@ static void boxes_check(size_t b,size_t m) } else { const char* pad = "\x02\x00\x00"; uint32_t psize = 3; - newlen = sizeof(newBox) + psize + iccProfile_.size(); + newlen = sizeof(newBox) + psize + static_cast(iccProfile_.size()); enforce(newlen <= static_cast(output.size() - outlen), Exiv2::kerCorruptedMetadata); ul2Data(reinterpret_cast(&newBox.length), newlen, bigEndian); ul2Data(reinterpret_cast(&newBox.type), newBox.type, bigEndian); @@ -766,9 +766,11 @@ static void boxes_check(size_t b,size_t m) #endif // Read chunk header. - long bufRead = io_->read(bheaderBuf.data(), bheaderBuf.size()); - if (io_->error()) throw Error(kerFailedToReadImageData); - if (bufRead != bheaderBuf.size()) throw Error(kerInputDataReadFailed); + size_t bufRead = io_->read(bheaderBuf.data(), bheaderBuf.size()); + if (io_->error()) + throw Error(kerFailedToReadImageData); + if (bufRead != bheaderBuf.size()) + throw Error(kerInputDataReadFailed); // Decode box header. @@ -810,7 +812,7 @@ static void boxes_check(size_t b,size_t m) throw Error(kerFailedToReadImageData); } - if (bufRead != static_cast(box.length - 8)) { + if (bufRead != (box.length - 8)) { #ifdef EXIV2_DEBUG_MESSAGES std::cout << "Exiv2::Jp2Image::doWriteMetadata: Cannot read source file data" << std::endl; #endif @@ -826,7 +828,8 @@ static void boxes_check(size_t b,size_t m) #ifdef EXIV2_DEBUG_MESSAGES std::cout << "Exiv2::Jp2Image::doWriteMetadata: Write JP2Header box (length: " << box.length << ")" << std::endl; #endif - if (outIo.write(newBuf.data(), newBuf.size()) != newBuf.size()) throw Error(kerImageWriteFailed); + if (outIo.write(newBuf.data(), newBuf.size()) != newBuf.size()) + throw Error(kerImageWriteFailed); // Write all updated metadata here, just after JP2Header. @@ -841,7 +844,7 @@ static void boxes_check(size_t b,size_t m) rawExif.copyBytes(0, &blob[0], blob.size()); DataBuf boxData(8 + 16 + rawExif.size()); - ul2Data(boxDataSize, boxData.size(), Exiv2::bigEndian); + ul2Data(boxDataSize, static_cast(boxData.size()), Exiv2::bigEndian); ul2Data(boxUUIDtype, kJp2BoxTypeUuid, Exiv2::bigEndian); boxData.copyBytes(0, boxDataSize, 4); boxData.copyBytes(4, boxUUIDtype, 4); @@ -852,7 +855,8 @@ static void boxes_check(size_t b,size_t m) std::cout << "Exiv2::Jp2Image::doWriteMetadata: Write box with Exif metadata (length: " << boxData.size() << std::endl; #endif - if (outIo.write(boxData.c_data(), boxData.size()) != boxData.size()) throw Error(kerImageWriteFailed); + if (outIo.write(boxData.c_data(), boxData.size()) != boxData.size()) + throw Error(kerImageWriteFailed); } } @@ -864,7 +868,7 @@ static void boxes_check(size_t b,size_t m) if (rawIptc.size() > 0) { DataBuf boxData(8 + 16 + rawIptc.size()); - ul2Data(boxDataSize, boxData.size(), Exiv2::bigEndian); + ul2Data(boxDataSize, static_cast(boxData.size()), Exiv2::bigEndian); ul2Data(boxUUIDtype, kJp2BoxTypeUuid, Exiv2::bigEndian); boxData.copyBytes(0, boxDataSize, 4); boxData.copyBytes(4, boxUUIDtype, 4); @@ -875,7 +879,8 @@ static void boxes_check(size_t b,size_t m) std::cout << "Exiv2::Jp2Image::doWriteMetadata: Write box with Iptc metadata (length: " << boxData.size() << std::endl; #endif - if (outIo.write(boxData.c_data(), boxData.size()) != boxData.size()) throw Error(kerImageWriteFailed); + if (outIo.write(boxData.c_data(), boxData.size()) != boxData.size()) + throw Error(kerImageWriteFailed); } } @@ -892,7 +897,7 @@ static void boxes_check(size_t b,size_t m) DataBuf xmp(reinterpret_cast(xmpPacket_.data()), static_cast(xmpPacket_.size())); DataBuf boxData(8 + 16 + xmp.size()); - ul2Data(boxDataSize, boxData.size(), Exiv2::bigEndian); + ul2Data(boxDataSize, static_cast(boxData.size()), Exiv2::bigEndian); ul2Data(boxUUIDtype, kJp2BoxTypeUuid, Exiv2::bigEndian); boxData.copyBytes(0, boxDataSize, 4); boxData.copyBytes(4, boxUUIDtype, 4); @@ -903,7 +908,8 @@ static void boxes_check(size_t b,size_t m) std::cout << "Exiv2::Jp2Image::doWriteMetadata: Write box with XMP metadata (length: " << boxData.size() << ")" << std::endl; #endif - if (outIo.write(boxData.c_data(), boxData.size()) != boxData.size()) throw Error(kerImageWriteFailed); + if (outIo.write(boxData.c_data(), boxData.size()) != boxData.size()) + throw Error(kerImageWriteFailed); } break; @@ -935,7 +941,8 @@ static void boxes_check(size_t b,size_t m) #ifdef EXIV2_DEBUG_MESSAGES std::cout << "Exiv2::Jp2Image::doWriteMetadata: write Uuid box (length: " << box.length << ")" << std::endl; #endif - if (outIo.write(boxBuf.c_data(), boxBuf.size()) != boxBuf.size()) throw Error(kerImageWriteFailed); + if (outIo.write(boxBuf.c_data(), boxBuf.size()) != boxBuf.size()) + throw Error(kerImageWriteFailed); } break; } @@ -945,7 +952,8 @@ static void boxes_check(size_t b,size_t m) #ifdef EXIV2_DEBUG_MESSAGES std::cout << "Exiv2::Jp2Image::doWriteMetadata: write box (length: " << box.length << ")" << std::endl; #endif - if (outIo.write(boxBuf.c_data(), boxBuf.size()) != boxBuf.size()) throw Error(kerImageWriteFailed); + if (outIo.write(boxBuf.c_data(), boxBuf.size()) != boxBuf.size()) + throw Error(kerImageWriteFailed); break; } diff --git a/src/jpgimage.cpp b/src/jpgimage.cpp index 72c2531b..16239c41 100644 --- a/src/jpgimage.cpp +++ b/src/jpgimage.cpp @@ -41,6 +41,7 @@ #include "fff.h" // + standard includes +#include // for EOF #include // for EOF #include #include @@ -99,10 +100,10 @@ namespace Exiv2 { return inRange(lo1,value,hi1) || inRange(lo2,value,hi2); } - bool Photoshop::isIrb(const byte* pPsData, - long sizePsData) + bool Photoshop::isIrb(const byte* pPsData, size_t sizePsData) { - if (sizePsData < 4) return false; + if (sizePsData < 4) + return false; for (auto&& i : irbId_) { assert(strlen(i) == 4); if (memcmp(pPsData, i, 4) == 0) @@ -111,8 +112,7 @@ namespace Exiv2 { return false; } - bool Photoshop::valid(const byte* pPsData, - long sizePsData) + bool Photoshop::valid(const byte* pPsData, size_t sizePsData) { const byte* record = nullptr; uint32_t sizeIptc = 0; @@ -121,8 +121,7 @@ namespace Exiv2 { const byte* pEnd = pPsData + sizePsData; int ret = 0; while (pCur < pEnd - && 0 == (ret = Photoshop::locateIptcIrb(pCur, static_cast(pEnd - pCur), - &record, &sizeHdr, &sizeIptc))) { + && 0 == (ret = Photoshop::locateIptcIrb(pCur, (pEnd - pCur), &record, &sizeHdr, &sizeIptc))) { pCur = record + sizeHdr + sizeIptc + (sizeIptc & 1); } return ret >= 0; @@ -132,7 +131,7 @@ namespace Exiv2 { // the format (in particular the header). So it remains to be confirmed // if this also makes sense for psTag != Photoshop::iptc int Photoshop::locateIrb(const byte* pPsData, - long sizePsData, + size_t sizePsData, uint16_t psTag, const byte** record, uint32_t *const sizeHdr, @@ -141,8 +140,12 @@ namespace Exiv2 { assert(record); assert(sizeHdr); assert(sizeData); + if (sizePsData < 12) { + return 3; + } + // Used for error checking - long position = 0; + size_t position = 0; #ifdef EXIV2_DEBUG_MESSAGES std::cerr << "Photoshop::locateIrb: "; #endif @@ -168,7 +171,7 @@ namespace Exiv2 { } uint32_t dataSize = getULong(pPsData + position, bigEndian); position += 4; - if (dataSize > static_cast(sizePsData - position)) { + if (dataSize > (sizePsData - position)) { #ifdef EXIV2_DEBUG_MESSAGES std::cerr << "Warning: " << "Invalid Photoshop IRB data size " @@ -206,10 +209,10 @@ namespace Exiv2 { return -2; } return 3; - } // Photoshop::locateIrb + } int Photoshop::locateIptcIrb(const byte* pPsData, - long sizePsData, + size_t sizePsData, const byte** record, uint32_t *const sizeHdr, uint32_t *const sizeData) @@ -219,7 +222,7 @@ namespace Exiv2 { } int Photoshop::locatePreviewIrb(const byte* pPsData, - long sizePsData, + size_t sizePsData, const byte** record, uint32_t *const sizeHdr, uint32_t *const sizeData) @@ -228,11 +231,10 @@ namespace Exiv2 { record, sizeHdr, sizeData); } - DataBuf Photoshop::setIptcIrb(const byte* pPsData, - long sizePsData, - const IptcData& iptcData) + DataBuf Photoshop::setIptcIrb(const byte* pPsData, size_t sizePsData, const IptcData& iptcData) { - if (sizePsData > 0) assert(pPsData); + if (sizePsData > 0) + assert(pPsData); #ifdef EXIV2_DEBUG_MESSAGES std::cerr << "IRB block at the beginning of Photoshop::setIptcIrb\n"; if (sizePsData == 0) std::cerr << " None.\n"; @@ -243,25 +245,24 @@ namespace Exiv2 { uint32_t sizeHdr = 0; DataBuf rc; // Safe to call with zero psData.size_ - if (0 > Photoshop::locateIptcIrb(pPsData, sizePsData, - &record, &sizeHdr, &sizeIptc)) { + if (0 > Photoshop::locateIptcIrb(pPsData, sizePsData, &record, &sizeHdr, &sizeIptc)) { return rc; } Blob psBlob; - const auto sizeFront = static_cast(record - pPsData); + const auto sizeFront = static_cast(record - pPsData); // Write data before old record. if (sizePsData > 0 && sizeFront > 0) { append(psBlob, pPsData, sizeFront); } // Write new iptc record if we have it DataBuf rawIptc = IptcParser::encode(iptcData); - if (rawIptc.size() > 0) { + if (!rawIptc.empty()) { std::array tmpBuf; - std::memcpy(tmpBuf.data(), Photoshop::irbId_[0], 4); + std::copy_n(Photoshop::irbId_[0], 4, tmpBuf.data()); us2Data(tmpBuf.data() + 4, iptc_, bigEndian); tmpBuf[6] = 0; tmpBuf[7] = 0; - ul2Data(tmpBuf.data() + 8, rawIptc.size(), bigEndian); + ul2Data(tmpBuf.data() + 8, static_cast(rawIptc.size()), bigEndian); append(psBlob, tmpBuf.data(), 12); append(psBlob, rawIptc.c_data(), rawIptc.size()); // Data is padded to be even (but not included in size) @@ -270,10 +271,9 @@ namespace Exiv2 { } // Write existing stuff after record, // skip the current and all remaining IPTC blocks - long pos = sizeFront; - while (0 == Photoshop::locateIptcIrb(pPsData + pos, sizePsData - pos, - &record, &sizeHdr, &sizeIptc)) { - const long newPos = static_cast(record - pPsData); + size_t pos = sizeFront; + while (0 == Photoshop::locateIptcIrb(pPsData + pos, sizePsData - pos, &record, &sizeHdr, &sizeIptc)) { + const auto newPos = static_cast(record - pPsData); // Copy data up to the IPTC IRB if (newPos > pos) { append(psBlob, pPsData + pos, newPos - pos); @@ -286,15 +286,16 @@ namespace Exiv2 { } // Data is rounded to be even if (!psBlob.empty()) - rc = DataBuf(&psBlob[0], static_cast(psBlob.size())); + rc = DataBuf(&psBlob[0], psBlob.size()); #ifdef EXIV2_DEBUG_MESSAGES std::cerr << "IRB block at the end of Photoshop::setIptcIrb\n"; - if (rc.size() == 0) std::cerr << " None.\n"; + if (rc.empty()) + std::cerr << " None.\n"; else hexdump(std::cerr, rc.c_data(), rc.size()); #endif return rc; - } // Photoshop::setIptcIrb + } bool JpegBase::markerHasLength(byte marker) { return (marker >= sof0_ && marker <= sof15_) || @@ -307,7 +308,7 @@ namespace Exiv2 { } JpegBase::JpegBase(ImageType type, BasicIo::UniquePtr io, bool create, - const byte initData[], long dataSize) + const byte initData[], size_t dataSize) : Image(type, mdExif | mdIptc | mdXmp | mdComment, std::move(io)) { if (create) { @@ -315,7 +316,7 @@ namespace Exiv2 { } } - int JpegBase::initImage(const byte initData[], long dataSize) + int JpegBase::initImage(const byte initData[], size_t dataSize) { if (io_->open() != 0) { return 4; @@ -424,7 +425,7 @@ namespace Exiv2 { // Append to psBlob append(psBlob, buf.c_data(16), size - 16); // Check whether psBlob is complete - if (!psBlob.empty() && Photoshop::valid(&psBlob[0], static_cast(psBlob.size()))) { + if (!psBlob.empty() && Photoshop::valid(&psBlob[0], psBlob.size())) { --search; foundCompletePsData = true; } @@ -467,7 +468,7 @@ namespace Exiv2 { << std::endl ; #endif // #1286 profile can be padded - long icc_size = size-2-14; + size_t icc_size = size-2-14; if (chunk==1 && chunks==1) { enforce(s <= static_cast(icc_size), kerInvalidIccProfile); icc_size = s; @@ -509,8 +510,7 @@ namespace Exiv2 { const byte* pCur = &psBlob[0]; const byte* pEnd = pCur + psBlob.size(); while ( pCur < pEnd - && 0 == Photoshop::locateIptcIrb(pCur, static_cast(pEnd - pCur), - &record, &sizeHdr, &sizeIptc)) { + && 0 == Photoshop::locateIptcIrb(pCur, pEnd - pCur, &record, &sizeHdr, &sizeIptc)) { #ifdef EXIV2_DEBUG_MESSAGES std::cerr << "Found IPTC IRB, size = " << sizeIptc << "\n"; #endif @@ -526,7 +526,7 @@ namespace Exiv2 { #endif iptcData_.clear(); } - } // psBlob.size() > 0 + } if (rc != 0) { #ifndef SUPPRESS_WARNINGS @@ -961,7 +961,7 @@ namespace Exiv2 { // Append to psBlob append(psBlob, buf.c_data(16), buf.size() - 16); // Check whether psBlob is complete - if (!psBlob.empty() && Photoshop::valid(&psBlob[0], static_cast(psBlob.size()))) { + if (!psBlob.empty() && Photoshop::valid(&psBlob[0], psBlob.size())) { foundCompletePsData = true; } } else if (marker == com_ && skipCom == notfound) { @@ -1048,7 +1048,7 @@ namespace Exiv2 { throw Error(kerImageWriteFailed); // Write new Exif data buffer - if (outIo.write(pExifData, static_cast(exifSize)) != static_cast(exifSize)) + if (outIo.write(pExifData, exifSize) != exifSize) throw Error(kerImageWriteFailed); if (outIo.error()) throw Error(kerImageWriteFailed); @@ -1078,7 +1078,7 @@ namespace Exiv2 { // Write new XMP packet if (outIo.write(reinterpret_cast(xmpPacket_.data()), - static_cast(xmpPacket_.size())) != static_cast(xmpPacket_.size())) + xmpPacket_.size()) != xmpPacket_.size()) throw Error(kerImageWriteFailed); if (outIo.error()) throw Error(kerImageWriteFailed); @@ -1093,14 +1093,14 @@ namespace Exiv2 { tmpBuf[1] = app2_; const long chunk_size = 256 * 256 - 40; // leave bytes for marker, header and padding - long size = iccProfile_.size(); + size_t size = iccProfile_.size(); assert(size > 0); // Because iccProfileDefined() == true if (size >= 255 * chunk_size) throw Error(kerTooLargeJpegSegment, "IccProfile"); - const long chunks = 1 + (size - 1) / chunk_size; + const size_t chunks = 1 + (size - 1) / chunk_size; assert(chunks <= 255); // Because size < 255 * chunk_size - for (long chunk = 0; chunk < chunks; chunk++) { - long bytes = size > chunk_size ? chunk_size : size; // bytes to write + for (size_t chunk = 0; chunk < chunks; chunk++) { + size_t bytes = size > chunk_size ? chunk_size : size; // bytes to write size -= bytes; // write JPEG marker (2 bytes) @@ -1128,14 +1128,14 @@ namespace Exiv2 { if (foundCompletePsData || iptcData_.count() > 0) { // 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.empty() ? &psBlob[0] : nullptr, - static_cast(psBlob.size()), iptcData_); + 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* chunkEnd = newPsData.size() == 0 ? nullptr : newPsData.c_data(newPsData.size()-1); + const byte* chunkEnd = newPsData.empty() ? nullptr : newPsData.c_data(newPsData.size()-1); while (chunkStart < chunkEnd) { // Determine size of next chunk - long chunkSize = static_cast(chunkEnd + 1 - chunkStart); + size_t chunkSize = (chunkEnd + 1 - chunkStart); if (chunkSize > maxChunkSize) { chunkSize = maxChunkSize; // Don't break at a valid IRB boundary @@ -1183,7 +1183,7 @@ namespace Exiv2 { if (outIo.write(tmpBuf.data(), 4) != 4) throw Error(kerImageWriteFailed); if (outIo.write(reinterpret_cast(const_cast(comment_.data())), - static_cast(comment_.length())) != static_cast(comment_.length())) + comment_.length()) != comment_.length()) throw Error(kerImageWriteFailed); if (outIo.putb(0) == EOF) throw Error(kerImageWriteFailed); @@ -1230,7 +1230,7 @@ namespace Exiv2 { throw Error(kerImageWriteFailed); DataBuf buf(4096); - long readSize = 0; + size_t readSize = 0; while ((readSize = io_->read(buf.data(), buf.size()))) { if (outIo.write(buf.c_data(), readSize) != readSize) throw Error(kerImageWriteFailed); diff --git a/src/makernote_int.cpp b/src/makernote_int.cpp index 4ac1e813..abd79432 100644 --- a/src/makernote_int.cpp +++ b/src/makernote_int.cpp @@ -241,7 +241,7 @@ namespace Exiv2 { uint32_t OlympusMnHeader::size() const { - return header_.size(); + return static_cast(header_.size()); } uint32_t OlympusMnHeader::ifdOffset() const @@ -283,7 +283,7 @@ namespace Exiv2 { uint32_t Olympus2MnHeader::size() const { - return header_.size(); + return static_cast(header_.size()); } uint32_t Olympus2MnHeader::ifdOffset() const @@ -331,7 +331,7 @@ namespace Exiv2 { uint32_t FujiMnHeader::size() const { - return header_.size(); + return static_cast(header_.size()); } uint32_t FujiMnHeader::ifdOffset() const @@ -470,12 +470,11 @@ namespace Exiv2 { assert(buf_.size() >= 10); ioWrapper.write(buf_.c_data(), 10); - // Todo: This removes any gap between the header and - // makernote IFD. The gap should be copied too. + /// \todo: This removes any gap between the header and makernote IFD. The gap should be copied too. TiffHeader th(byteOrder); DataBuf buf = th.write(); ioWrapper.write(buf.c_data(), buf.size()); - return 10 + buf.size(); + return 10 + static_cast(buf.size()); } // Nikon3MnHeader::write void Nikon3MnHeader::setByteOrder(ByteOrder byteOrder) @@ -542,7 +541,7 @@ namespace Exiv2 { uint32_t PentaxDngMnHeader::size() const { - return header_.size(); + return static_cast(header_.size()); } uint32_t PentaxDngMnHeader::baseOffset(uint32_t mnOffset) const @@ -589,7 +588,7 @@ namespace Exiv2 { uint32_t PentaxMnHeader::size() const { - return header_.size(); + return static_cast(header_.size()); } uint32_t PentaxMnHeader::ifdOffset() const @@ -1163,7 +1162,7 @@ namespace Exiv2 { } buf.alloc(size); buf.copyBytes(0, pData, buf.size()); - ncrypt(buf.data(nci->start_), buf.size() - nci->start_, count, serial); + ncrypt(buf.data(nci->start_), static_cast(buf.size()) - nci->start_, count, serial); return buf; } diff --git a/src/mrwimage.cpp b/src/mrwimage.cpp index be96c649..6ea0f78b 100644 --- a/src/mrwimage.cpp +++ b/src/mrwimage.cpp @@ -141,7 +141,7 @@ namespace Exiv2 { iptcData_, xmpData_, buf.c_data(), - buf.size()); + static_cast(buf.size())); setByteOrder(bo); } // MrwImage::readMetadata diff --git a/src/olympusmn_int.cpp b/src/olympusmn_int.cpp index 9c71c469..42b4b3fb 100644 --- a/src/olympusmn_int.cpp +++ b/src/olympusmn_int.cpp @@ -1400,8 +1400,8 @@ namespace Exiv2 { } char ch; - int size = value.size(); - for (int i = 0; i < size && ((ch = static_cast(value.toInt64(i))) != '\0'); i++) { + size_t size = value.size(); + for (size_t i = 0; i < size && ((ch = static_cast(value.toInt64(i))) != '\0'); i++) { os << ch; } return os; diff --git a/src/panasonicmn_int.cpp b/src/panasonicmn_int.cpp index cbe1a65a..1c468bea 100644 --- a/src/panasonicmn_int.cpp +++ b/src/panasonicmn_int.cpp @@ -659,19 +659,18 @@ namespace Exiv2 { { if(value.size()>0 && value.typeId() == undefined) { - for(long i=0; i< value.size(); i++) + for(size_t i=0; i< value.size(); i++) { if(value.toInt64(i)==0) { break; - }; + } os << static_cast(value.toInt64(i)); - }; + } return os; } return os << value; - ; } // PanasonicMakerNote::printPanasonicText // Manometer Pressure diff --git a/src/pgfimage.cpp b/src/pgfimage.cpp index d6e3ae82..8b07683b 100644 --- a/src/pgfimage.cpp +++ b/src/pgfimage.cpp @@ -134,13 +134,17 @@ namespace Exiv2 { std::cout << "Exiv2::PgfImage::readMetadata: Found Image data (" << size << " bytes)\n"; #endif - if (size < 0 || static_cast(size) > io_->size()) throw Error(kerInputDataReadFailed); - if (size == 0) return; + if (size < 0 || static_cast(size) > io_->size()) + throw Error(kerInputDataReadFailed); + if (size == 0) + return; DataBuf imgData(size); - long bufRead = io_->read(imgData.data(), imgData.size()); - if (io_->error()) throw Error(kerFailedToReadImageData); - if (bufRead != imgData.size()) throw Error(kerInputDataReadFailed); + const size_t bufRead = io_->read(imgData.data(), imgData.size()); + if (io_->error()) + throw Error(kerFailedToReadImageData); + if (bufRead != imgData.size()) + throw Error(kerInputDataReadFailed); auto image = Exiv2::ImageFactory::open(imgData.c_data(), imgData.size()); image->readMetadata(); @@ -211,7 +215,7 @@ namespace Exiv2 { if (outIo.putb(mnb) == EOF) throw Error(kerImageWriteFailed); // Write new Header size. - uint32_t newHeaderSize = header.size() + imgSize; + uint32_t newHeaderSize = static_cast(header.size()) + imgSize; DataBuf buffer(4); buffer.copyBytes(0, &newHeaderSize, 4); byteSwap_(buffer,0,bSwap_); @@ -227,15 +231,17 @@ namespace Exiv2 { #endif // Write Header data. - if (outIo.write(header.c_data(), header.size()) != header.size()) throw Error(kerImageWriteFailed); + if (outIo.write(header.c_data(), header.size()) != header.size()) + throw Error(kerImageWriteFailed); // Write new metadata byte array. - if (outIo.write(imgBuf.c_data(), imgBuf.size()) != imgBuf.size()) throw Error(kerImageWriteFailed); + if (outIo.write(imgBuf.c_data(), imgBuf.size()) != imgBuf.size()) + throw Error(kerImageWriteFailed); // Copy the rest of PGF image data. DataBuf buf(4096); - long readSize = 0; + size_t readSize = 0; while ((readSize=io_->read(buf.data(), buf.size()))) { if (outIo.write(buf.c_data(), readSize) != readSize) throw Error(kerImageWriteFailed); @@ -263,9 +269,11 @@ namespace Exiv2 { uint32_t PgfImage::readPgfHeaderSize(BasicIo& iIo) const { DataBuf buffer(4); - long bufRead = iIo.read(buffer.data(), buffer.size()); - if (iIo.error()) throw Error(kerFailedToReadImageData); - if (bufRead != buffer.size()) throw Error(kerInputDataReadFailed); + const size_t bufRead = iIo.read(buffer.data(), buffer.size()); + if (iIo.error()) + throw Error(kerFailedToReadImageData); + if (bufRead != buffer.size()) + throw Error(kerInputDataReadFailed); int headerSize = static_cast(byteSwap_(buffer, 0, bSwap_)); if (headerSize <= 0 ) throw Error(kerNoImageInInputData); @@ -280,9 +288,11 @@ namespace Exiv2 { DataBuf PgfImage::readPgfHeaderStructure(BasicIo& iIo, uint32_t& width, uint32_t& height) const { DataBuf header(16); - long bufRead = iIo.read(header.data(), header.size()); - if (iIo.error()) throw Error(kerFailedToReadImageData); - if (bufRead != header.size()) throw Error(kerInputDataReadFailed); + size_t bufRead = iIo.read(header.data(), header.size()); + if (iIo.error()) + throw Error(kerFailedToReadImageData); + if (bufRead != header.size()) + throw Error(kerInputDataReadFailed); DataBuf work(8); // don't disturb the binary data - doWriteMetadata reuses it work.copyBytes(0,header.c_data(),8); diff --git a/src/pngchunk_int.cpp b/src/pngchunk_int.cpp index 9e89cbc8..ea787960 100644 --- a/src/pngchunk_int.cpp +++ b/src/pngchunk_int.cpp @@ -56,7 +56,7 @@ PNG tags : http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/PNG */ namespace { - constexpr int nullSeparators = 2; + constexpr size_t nullSeparators = 2; } // ***************************************************************************** @@ -101,24 +101,18 @@ namespace Exiv2 DataBuf PngChunk::keyTXTChunk(const DataBuf& data, bool stripHeader) { // From a tEXt, zTXt, or iTXt chunk, we get the keyword which is null terminated. - const int offset = stripHeader ? 8 : 0; + const size_t offset = stripHeader ? 8ul : 0ul; if (data.size() <= offset) throw Error(kerFailedToReadImageData); - // Search for null char until the end of the DataBuf - const byte* dataPtr = data.c_data(); - int keysize = offset; - while (keysize < data.size() && dataPtr[keysize] != 0) { - keysize++; - } - - if (keysize == data.size()) + auto it = std::find(data.cbegin() + offset, data.cend(), 0); + if (it == data.cend()) throw Error(kerFailedToReadImageData); - return DataBuf(dataPtr + offset, keysize - offset); + return DataBuf(data.c_data() + offset, std::distance(data.cbegin(), it)- offset); } - DataBuf PngChunk::parseTXTChunk(const DataBuf& data, int keysize, TxtChunkType type) + DataBuf PngChunk::parseTXTChunk(const DataBuf& data, size_t keysize, TxtChunkType type) { DataBuf arr; @@ -139,21 +133,21 @@ namespace Exiv2 // compressed string after the compression technique spec const byte* compressedText = data.c_data(keysize + nullSeparators); - long compressedTextSize = data.size() - keysize - nullSeparators; + size_t compressedTextSize = data.size() - keysize - nullSeparators; enforce(compressedTextSize < data.size(), kerCorruptedMetadata); - zlibUncompress(compressedText, compressedTextSize, arr); + zlibUncompress(compressedText, static_cast(compressedTextSize), arr); } else if (type == tEXt_Chunk) { - enforce(data.size() >= Safe::add(keysize, 1), Exiv2::kerCorruptedMetadata); + enforce(data.size() >= Safe::add(keysize, static_cast(1)), Exiv2::kerCorruptedMetadata); // Extract a non-compressed Latin-1 text chunk // the text comes after the key, but isn't null terminated const byte* text = data.c_data(keysize + 1); - long textsize = data.size() - keysize - 1; + size_t textsize = data.size() - keysize - 1; arr = DataBuf(text, textsize); } else if (type == iTXt_Chunk) { - enforce(data.size() >= Safe::add(keysize, 3), Exiv2::kerCorruptedMetadata); + enforce(data.size() >= Safe::add(keysize, static_cast(3)), Exiv2::kerCorruptedMetadata); const size_t nullCount = std::count(data.c_data(keysize + 3), data.c_data(data.size()-1), '\0'); enforce(nullCount >= nullSeparators, Exiv2::kerCorruptedMetadata); @@ -169,21 +163,19 @@ namespace Exiv2 // language description string after the compression technique spec const size_t languageTextMaxSize = data.size() - keysize - 3; - std::string languageText = - string_from_unterminated(data.c_str(Safe::add(keysize, 3)), languageTextMaxSize); + std::string languageText = string_from_unterminated(data.c_str(keysize+3), languageTextMaxSize); const size_t languageTextSize = languageText.size(); - enforce(static_cast(data.size()) >= - Safe::add(static_cast(Safe::add(keysize, 4)), languageTextSize), - Exiv2::kerCorruptedMetadata); + enforce(data.size() >= Safe::add(Safe::add(keysize, static_cast(4)), languageTextSize), + Exiv2::kerCorruptedMetadata); // translated keyword string after the language description std::string translatedKeyText = string_from_unterminated( data.c_str(keysize + 3 + languageTextSize + 1), data.size() - (keysize + 3 + languageTextSize + 1)); - const auto translatedKeyTextSize = static_cast(translatedKeyText.size()); + const size_t translatedKeyTextSize = translatedKeyText.size(); if ((compressionFlag == 0x00) || (compressionFlag == 0x01 && compressionMethod == 0x00)) { - enforce(Safe::add(static_cast(keysize + 3 + languageTextSize + 1), - Safe::add(translatedKeyTextSize, 1U)) <= static_cast(data.size()), + enforce(Safe::add(keysize + 3 + languageTextSize + 1, + Safe::add(translatedKeyTextSize, static_cast(1))) <= data.size(), Exiv2::kerCorruptedMetadata); const byte* text = data.c_data(keysize + 3 + languageTextSize + 1 + translatedKeyTextSize + 1); @@ -195,8 +187,6 @@ namespace Exiv2 #ifdef EXIV2_DEBUG_MESSAGES std::cout << "Exiv2::PngChunk::parseTXTChunk: We found an uncompressed iTXt field\n"; #endif - - arr.alloc(textsize); arr = DataBuf(text, textsize); } else if (compressionFlag == 0x01 && compressionMethod == 0x00) { // then it's a zlib compressed iTXt chunk @@ -224,7 +214,7 @@ namespace Exiv2 return arr; } - void PngChunk::parseChunkContent(Image* pImage, const byte* key, long keySize, const DataBuf& arr) + void PngChunk::parseChunkContent(Image* pImage, const byte* key, size_t keySize, const DataBuf& arr) { // We look if an ImageMagick EXIF raw profile exist. @@ -232,16 +222,16 @@ namespace Exiv2 (memcmp("Raw profile type exif", key, 21) == 0 || memcmp("Raw profile type APP1", key, 21) == 0) && pImage->exifData().empty()) { DataBuf exifData = readRawProfile(arr, false); - long length = exifData.size(); + size_t length = exifData.size(); - if (length > 0) { + if (length >= 6) { // length should have at least the size of exifHeader // Find the position of Exif header in bytes array. + const std::array exifHeader {0x45, 0x78, 0x69, 0x66, 0x00, 0x00}; + size_t pos = std::numeric_limits::max(); - const byte exifHeader[] = {0x45, 0x78, 0x69, 0x66, 0x00, 0x00}; - long pos = -1; - - for (long i = 0; i < length - static_cast(sizeof(exifHeader)); i++) { - if (exifData.cmpBytes(i, exifHeader, sizeof(exifHeader)) == 0) { + /// \todo Find substring inside an string + for (size_t i = 0; i < length - exifHeader.size(); i++) { + if (exifData.cmpBytes(i, exifHeader.data(), exifHeader.size()) == 0) { pos = i; break; } @@ -249,14 +239,14 @@ namespace Exiv2 // If found it, store only these data at from this place. - if (pos != -1) { + if (pos != std::numeric_limits::max()) { #ifdef EXIV2_DEBUG_MESSAGES std::cout << "Exiv2::PngChunk::parseChunkContent: Exif header found at position " << pos << "\n"; #endif pos = pos + sizeof(exifHeader); ByteOrder bo = TiffParser::decode(pImage->exifData(), pImage->iptcData(), pImage->xmpData(), - exifData.c_data(pos), length - pos); + exifData.c_data(pos), static_cast(length - pos)); pImage->setByteOrder(bo); } else { #ifndef SUPPRESS_WARNINGS @@ -279,8 +269,7 @@ namespace Exiv2 const byte* pEnd = psData.c_data(psData.size()-1); const byte* pCur = psData.c_data(); - while (pCur < pEnd && 0 == Photoshop::locateIptcIrb(pCur, static_cast(pEnd - pCur), &record, - &sizeHdr, &sizeIptc)) { + while (pCur < pEnd && 0 == Photoshop::locateIptcIrb(pCur, pEnd - pCur, &record, &sizeHdr, &sizeIptc)) { if (sizeIptc) { #ifdef EXIV2_DEBUG_MESSAGES std::cerr << "Found IPTC IRB, size = " << sizeIptc << "\n"; @@ -298,7 +287,8 @@ namespace Exiv2 pImage->clearIptcData(); } // If there is no IRB, try to decode the complete chunk data - if (iptcBlob.empty() && IptcParser::decode(pImage->iptcData(), psData.c_data(), psData.size())) { + if (iptcBlob.empty() && IptcParser::decode(pImage->iptcData(), psData.c_data(), + static_cast(psData.size()))) { #ifndef SUPPRESS_WARNINGS EXV_WARNING << "Failed to decode IPTC metadata.\n"; #endif @@ -311,7 +301,7 @@ namespace Exiv2 if (keySize >= 20 && memcmp("Raw profile type xmp", key, 20) == 0 && pImage->xmpData().empty()) { DataBuf xmpBuf = readRawProfile(arr, false); - long length = xmpBuf.size(); + size_t length = xmpBuf.size(); if (length > 0) { std::string& xmpPacket = pImage->xmpPacket(); @@ -534,15 +524,16 @@ namespace Exiv2 DataBuf PngChunk::readRawProfile(const DataBuf& text, bool iTXt) { + if (text.empty()) { + return DataBuf(); + } + DataBuf info; unsigned char unhex[103] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15}; - if (text.size() == 0) { - return DataBuf(); - } if (iTXt) { info.alloc(text.size()); @@ -578,15 +569,14 @@ namespace Exiv2 } // Parse the length. - long length = 0; + size_t length = 0; while ('0' <= *sp && *sp <= '9') { - // Compute the new length using unsigned long, so that we can - // check for overflow. - const unsigned long newlength = (10 * static_cast(length)) + (*sp - '0'); - if (newlength > static_cast(std::numeric_limits::max())) { + // Compute the new length using unsigned long, so that we can check for overflow. + const size_t newlength = (10 * length) + (*sp - '0'); + if (newlength > std::numeric_limits::max()) { return DataBuf(); // Integer overflow. } - length = static_cast(newlength); + length = newlength; sp++; if (sp == eot) { return DataBuf(); @@ -597,7 +587,7 @@ namespace Exiv2 return DataBuf(); } - enforce(length <= (eot - sp) / 2, Exiv2::kerCorruptedMetadata); + enforce(length <= static_cast(eot - sp) / 2, Exiv2::kerCorruptedMetadata); // Allocate space if (length == 0) { @@ -616,9 +606,9 @@ namespace Exiv2 // Copy profile, skipping white space and column 1 "=" signs unsigned char* dp = info.data(); // decode pointer - unsigned int nibbles = length * 2; + size_t nibbles = length * 2; - for (long i = 0; i < static_cast(nibbles); i++) { + for (size_t i = 0; i < nibbles; i++) { enforce(sp < eot, Exiv2::kerCorruptedMetadata); while (*sp < '0' || (*sp > '9' && *sp < 'a') || *sp > 'f') { if (*sp == '\0') { diff --git a/src/pngchunk_int.hpp b/src/pngchunk_int.hpp index 48806bc0..77cf0e7a 100644 --- a/src/pngchunk_int.hpp +++ b/src/pngchunk_int.hpp @@ -113,9 +113,7 @@ namespace Exiv2 { @brief Parse PNG Text chunk to determine type and extract content. Supported Chunk types are tTXt, zTXt, and iTXt. */ - static DataBuf parseTXTChunk(const DataBuf& data, - int keysize, - TxtChunkType type); + static DataBuf parseTXTChunk(const DataBuf& data, size_t keysize, TxtChunkType type); /*! @brief Parse PNG chunk contents to extract metadata container and assign it to image. @@ -126,7 +124,7 @@ namespace Exiv2 { Xmp packet generated by Adobe ==> Image Xmp metadata. Description string ==> Image Comments. */ - static void parseChunkContent(Image* pImage, const byte* key, long keySize, const DataBuf& arr); + static void parseChunkContent(Image* pImage, const byte* key, size_t keySize, const DataBuf& arr); /*! @brief Return a compressed (zTXt) or uncompressed (tEXt) PNG ASCII text chunk @@ -157,9 +155,7 @@ namespace Exiv2 { /*! @brief Wrapper around zlib to uncompress a PNG chunk content. */ - static void zlibUncompress(const byte* compressedText, - unsigned int compressedTextSize, - DataBuf& arr); + static void zlibUncompress(const byte* compressedText, unsigned int compressedTextSize, DataBuf& arr); /*! @brief Wrapper around zlib to compress a PNG chunk content. diff --git a/src/pngimage.cpp b/src/pngimage.cpp index 6c567084..3db06f30 100644 --- a/src/pngimage.cpp +++ b/src/pngimage.cpp @@ -62,7 +62,7 @@ namespace inline bool compare(const char* str, const Exiv2::DataBuf& buf, size_t length) { assert(strlen(str) <= length); - const long minlen = std::min(static_cast(length), buf.size()); + const auto minlen = std::min(length, buf.size()); return buf.cmpBytes(0, str, minlen) == 0; } } // namespace @@ -108,7 +108,7 @@ namespace Exiv2 { result.alloc(uncompressedLen); zlibResult = uncompress(result.data(),&uncompressedLen,bytes,length); // if result buffer is large than necessary, redo to fit perfectly. - if (zlibResult == Z_OK && static_cast(uncompressedLen) < result.size()) { + if (zlibResult == Z_OK && uncompressedLen < result.size()) { result.reset(); result.alloc(uncompressedLen); @@ -240,15 +240,17 @@ namespace Exiv2 { out << " address | chunk | length | data | checksum" << std::endl; } - const long imgSize = static_cast(io_->size()); + const size_t imgSize = io_->size(); DataBuf cheaderBuf(8); while( !io_->eof() && ::strcmp(chType,"IEND") ) { size_t address = io_->tell(); - long bufRead = io_->read(cheaderBuf.data(), cheaderBuf.size()); - if (io_->error()) throw Error(kerFailedToReadImageData); - if (bufRead != cheaderBuf.size()) throw Error(kerInputDataReadFailed); + size_t bufRead = io_->read(cheaderBuf.data(), cheaderBuf.size()); + if (io_->error()) + throw Error(kerFailedToReadImageData); + if (bufRead != cheaderBuf.size()) + throw Error(kerInputDataReadFailed); // Decode chunk data length. const uint32_t dataOffset = cheaderBuf.read_uint32(0, Exiv2::bigEndian); @@ -260,14 +262,14 @@ namespace Exiv2 { long restore = io_->tell(); if( restore == -1 || dataOffset > uint32_t(0x7FFFFFFF) - || static_cast(dataOffset) > imgSize - restore + || dataOffset > imgSize - restore ){ throw Exiv2::Error(kerFailedToReadImageData); } DataBuf buff(dataOffset); bufRead = io_->read(buff.data(),dataOffset); - enforce(bufRead == static_cast(dataOffset), kerFailedToReadImageData); + enforce(bufRead == dataOffset, kerFailedToReadImageData); io_->seek(restore, BasicIo::beg); // format output @@ -319,11 +321,11 @@ namespace Exiv2 { if( bDump ) { DataBuf dataBuf; - enforce(static_cast(dataOffset) < static_cast(std::numeric_limits::max()), kerFailedToReadImageData); - DataBuf data(static_cast(dataOffset) + 1); + enforce(dataOffset < std::numeric_limits::max(), kerFailedToReadImageData); + DataBuf data(dataOffset + 1ul); data.write_uint8(dataOffset, 0); - bufRead = io_->read(data.data(), static_cast(dataOffset)); - enforce(bufRead == static_cast(dataOffset), kerFailedToReadImageData); + bufRead = io_->read(data.data(), dataOffset); + enforce(bufRead == dataOffset, kerFailedToReadImageData); io_->seek(restore, BasicIo::beg); size_t name_l = std::strlen(data.c_str()) + 1; // leading string length @@ -335,10 +337,10 @@ namespace Exiv2 { // 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), static_cast(dataOffset - name_l), dataBuf); } if ( zTXt || iCCP ) { - bGood = zlibToDataBuf(data.c_data(name_l + 1), static_cast(dataOffset - name_l - 1), dataBuf); // +1 = 'compressed' flag + bGood = zlibToDataBuf(data.c_data(name_l + 1), static_cast(dataOffset - name_l - 1), dataBuf); // +1 = 'compressed' flag } if ( iTXt ) { bGood = (3 <= dataOffset) && (start < dataOffset-3); // good if not a nul chunk @@ -362,7 +364,7 @@ namespace Exiv2 { if ( parsedBuf.size() ) { if ( bExif ) { // create memio object with the data, then print the structure - MemIo p(parsedBuf.c_data(6),parsedBuf.size()-6); + MemIo p(parsedBuf.c_data(6), parsedBuf.size()-6); printTiffStructure(p,out,option,depth); } if ( bIptc ) { @@ -400,7 +402,8 @@ namespace Exiv2 { } } io_->seek(dataOffset+4, BasicIo::cur);// jump past checksum - if (io_->error()) throw Error(kerFailedToReadImageData); + if (io_->error()) + throw Error(kerFailedToReadImageData); } } } @@ -410,7 +413,7 @@ namespace Exiv2 { #ifdef EXIV2_DEBUG_MESSAGES std::cout << "Exiv2::PngImage::readMetadata: Position: " << io.tell() << std::endl; #endif - long bufRead = io.read(buffer.data(), buffer.size()); + const size_t bufRead = io.read(buffer.data(), buffer.size()); if (io.error()) { throw Error(kerFailedToReadImageData); } @@ -434,7 +437,7 @@ namespace Exiv2 { } clearMetadata(); - const long imgSize = static_cast(io_->size()); + const size_t imgSize = io_->size(); DataBuf cheaderBuf(8); // Chunk header: 4 bytes (data size) + 4 bytes (chunk type). while(!io_->eof()) @@ -446,7 +449,7 @@ namespace Exiv2 { long pos = io_->tell(); if (pos == -1 || chunkLength > uint32_t(0x7FFFFFFF) || - static_cast(chunkLength) > imgSize - pos) { + chunkLength > imgSize - pos) { throw Exiv2::Error(kerFailedToReadImageData); } @@ -482,7 +485,7 @@ namespace Exiv2 { iptcData(), xmpData(), chunkData.c_data(), - chunkData.size()); + static_cast(chunkData.size())); setByteOrder(bo); } else if (chunkType == "iCCP") { // The ICC profile name can vary from 1-79 characters. @@ -538,8 +541,10 @@ namespace Exiv2 { void PngImage::doWriteMetadata(BasicIo& outIo) { - if (!io_->isopen()) throw Error(kerInputDataReadFailed); - if (!outIo.isopen()) throw Error(kerImageWriteFailed); + if (!io_->isopen()) + throw Error(kerInputDataReadFailed); + if (!outIo.isopen()) + throw Error(kerImageWriteFailed); #ifdef EXIV2_DEBUG_MESSAGES std::cout << "Exiv2::PngImage::doWriteMetadata: Writing PNG file " << io_->path() << "\n"; @@ -551,29 +556,34 @@ namespace Exiv2 { } // Write PNG Signature. - if (outIo.write(pngSignature, 8) != 8) throw Error(kerImageWriteFailed); + if (outIo.write(pngSignature, 8) != 8) + throw Error(kerImageWriteFailed); DataBuf cheaderBuf(8); // Chunk header : 4 bytes (data size) + 4 bytes (chunk type). while(!io_->eof()) { // Read chunk header. - long bufRead = io_->read(cheaderBuf.data(), 8); - if (io_->error()) throw Error(kerFailedToReadImageData); - if (bufRead != 8) throw Error(kerInputDataReadFailed); + size_t bufRead = io_->read(cheaderBuf.data(), 8); + if (io_->error()) + throw Error(kerFailedToReadImageData); + if (bufRead != 8) + throw Error(kerInputDataReadFailed); // Decode chunk data length. uint32_t dataOffset = cheaderBuf.read_uint32(0, Exiv2::bigEndian); - if (dataOffset > 0x7FFFFFFF) throw Exiv2::Error(kerFailedToReadImageData); + if (dataOffset > 0x7FFFFFFF) + throw Exiv2::Error(kerFailedToReadImageData); // Read whole chunk : Chunk header + Chunk data (not fixed size - can be null) + CRC (4 bytes). DataBuf chunkBuf(8 + dataOffset + 4); // Chunk header (8 bytes) + Chunk data + CRC (4 bytes). chunkBuf.copyBytes(0, cheaderBuf.c_data(), 8); // Copy header. bufRead = io_->read(chunkBuf.data(8), dataOffset + 4); // Extract chunk data + CRC - if (io_->error()) throw Error(kerFailedToReadImageData); - if (bufRead != static_cast(dataOffset) + 4L) + if (io_->error()) + throw Error(kerFailedToReadImageData); + if (bufRead != static_cast(dataOffset) + 4) throw Error(kerInputDataReadFailed); char szChunk[5]; @@ -597,15 +607,15 @@ namespace Exiv2 { #ifdef EXIV2_DEBUG_MESSAGES std::cout << "Exiv2::PngImage::doWriteMetadata: Write IHDR chunk (length: " << dataOffset << ")\n"; #endif - if (outIo.write(chunkBuf.data(), chunkBuf.size()) != chunkBuf.size()) throw Error(kerImageWriteFailed); + if (outIo.write(chunkBuf.data(), chunkBuf.size()) != chunkBuf.size()) + throw Error(kerImageWriteFailed); // Write all updated metadata here, just after IHDR. if (!comment_.empty()) { // Update Comment data to a new PNG chunk std::string chunk = PngChunk::makeMetadataChunk(comment_, mdComment); - if (outIo.write(reinterpret_cast(chunk.data()), static_cast(chunk.size())) != - static_cast(chunk.size())) { + if (outIo.write(reinterpret_cast(chunk.data()), chunk.size()) != chunk.size()) { throw Error(kerImageWriteFailed); } } @@ -620,8 +630,7 @@ namespace Exiv2 { std::string rawExif = std::string(exifHeader, 6) + std::string(reinterpret_cast(&blob[0]), blob.size()); std::string chunk = PngChunk::makeMetadataChunk(rawExif, mdExif); - if (outIo.write(reinterpret_cast(chunk.data()), static_cast(chunk.size())) != - static_cast(chunk.size())) { + if (outIo.write(reinterpret_cast(chunk.data()), chunk.size()) != chunk.size()) { throw Error(kerImageWriteFailed); } } @@ -635,8 +644,7 @@ namespace Exiv2 { { std::string rawIptc(newPsData.c_str(), newPsData.size()); std::string chunk = PngChunk::makeMetadataChunk(rawIptc, mdIptc); - if (outIo.write(reinterpret_cast(chunk.data()), static_cast(chunk.size())) != - static_cast(chunk.size())) { + if (outIo.write(reinterpret_cast(chunk.data()), chunk.size()) != chunk.size()) { throw Error(kerImageWriteFailed); } } @@ -644,9 +652,9 @@ namespace Exiv2 { if ( iccProfileDefined() ) { DataBuf compressed; - if ( zlibToCompressed(iccProfile_.c_data(),iccProfile_.size(),compressed) ) { + if ( zlibToCompressed(iccProfile_.c_data(), static_cast(iccProfile_.size()), compressed) ) { const auto nameLength = static_cast(profileName_.size()); - const uint32_t chunkLength = nameLength + 2 + compressed.size() ; + const uint32_t chunkLength = nameLength + 2 + static_cast(compressed.size()); byte length[4]; ul2Data (length,chunkLength,bigEndian); @@ -655,7 +663,7 @@ namespace Exiv2 { tmp = crc32(tmp, typeICCP, 4); tmp = crc32(tmp, (const Bytef*)profileName_.data(), nameLength); tmp = crc32(tmp, nullComp, 2); - tmp = crc32(tmp, compressed.c_data(), compressed.size()); + tmp = crc32(tmp, compressed.c_data(), static_cast(compressed.size())); byte crc[4]; ul2Data(crc, tmp, bigEndian); @@ -685,8 +693,8 @@ namespace Exiv2 { if (!xmpPacket_.empty()) { // Update XMP data to a new PNG chunk std::string chunk = PngChunk::makeMetadataChunk(xmpPacket_, mdXmp); - if (outIo.write(reinterpret_cast(chunk.data()), static_cast(chunk.size())) != - static_cast(chunk.size())) { + if (outIo.write(reinterpret_cast(chunk.data()), chunk.size()) != + chunk.size()) { throw Error(kerImageWriteFailed); } } @@ -721,7 +729,8 @@ namespace Exiv2 { std::cout << "Exiv2::PngImage::doWriteMetadata: copy " << szChunk << " chunk (length: " << dataOffset << ")" << std::endl; #endif - if (outIo.write(chunkBuf.c_data(), chunkBuf.size()) != chunkBuf.size()) throw Error(kerImageWriteFailed); + if (outIo.write(chunkBuf.c_data(), chunkBuf.size()) != chunkBuf.size()) + throw Error(kerImageWriteFailed); } } diff --git a/src/preview.cpp b/src/preview.cpp index 4141ba5b..3266296e 100644 --- a/src/preview.cpp +++ b/src/preview.cpp @@ -140,7 +140,7 @@ namespace { uint32_t height_; //! Preview image size in bytes - uint32_t size_; + size_t size_; //! True if the source image contains a preview image of given type bool valid_; @@ -197,7 +197,7 @@ namespace { static const Param param_[]; //! Offset value - uint32_t offset_; + size_t offset_; }; //! Function to create new LoaderExifJpeg @@ -424,7 +424,7 @@ namespace { if (nativePreview_.filter_.empty()) { size_ = nativePreview_.size_; } else { - size_ = getData().size(); + size_ = static_cast(getData().size()); } } @@ -496,11 +496,15 @@ namespace { bool LoaderNative::readDimensions() { - if (!valid()) return false; - if (width_ != 0 || height_ != 0) return true; + if (!valid()) + return false; + if (width_ != 0 || height_ != 0) + return true; const DataBuf data = getData(); - if (data.size() == 0) return false; + if (data.empty()) + return false; + try { auto image = ImageFactory::open(data.c_data(), data.size()); if (!image) @@ -618,7 +622,8 @@ namespace { size_ = pos->size(); // direct data } - if (size_ == 0) return; + if (size_ == 0) + return; valid_ = true; } @@ -644,7 +649,7 @@ namespace { if (pos != image_.exifData().end()) { DataBuf buf = pos->dataArea(); // indirect data - if (buf.size() == 0) { // direct data + if (buf.empty()) { // direct data buf = DataBuf(pos->size()); pos->copy(buf.data(), invalidByteOrder); } @@ -658,10 +663,12 @@ namespace { bool LoaderExifDataJpeg::readDimensions() { - if (!valid()) return false; + if (!valid()) + return false; DataBuf buf = getData(); - if (buf.size() == 0) return false; + if (buf.empty()) + return false; try { auto image = ImageFactory::open(buf.c_data(), buf.size()); @@ -685,14 +692,16 @@ namespace { { const ExifData &exifData = image_.exifData(); - int offsetCount = 0; + size_t offsetCount = 0; ExifData::const_iterator pos; // check if the group_ contains a preview image if (param_[parIdx].checkTag_) { pos = exifData.findKey(ExifKey(param_[parIdx].checkTag_)); - if (pos == exifData.end()) return; - if (param_[parIdx].checkValue_ && pos->toString() != param_[parIdx].checkValue_) return; + if (pos == exifData.end()) + return; + if (param_[parIdx].checkValue_ && pos->toString() != param_[parIdx].checkValue_) + return; } pos = exifData.findKey(ExifKey(std::string("Exif.") + group_ + ".StripOffsets")); @@ -703,20 +712,24 @@ namespace { } else { pos = exifData.findKey(ExifKey(std::string("Exif.") + group_ + ".TileOffsets")); - if (pos == exifData.end()) return; + if (pos == exifData.end()) + return; offsetTag_ = "TileOffsets"; sizeTag_ = "TileByteCounts"; offsetCount = pos->value().count(); } pos = exifData.findKey(ExifKey(std::string("Exif.") + group_ + '.' + sizeTag_)); - if (pos == exifData.end()) return; - if (offsetCount != pos->value().count()) return; - for (int i = 0; i < offsetCount; i++) { - size_ += pos->toUint32(i); + if (pos == exifData.end()) + return; + if (offsetCount != pos->value().count()) + return; + for (size_t i = 0; i < offsetCount; i++) { + size_ += pos->toUint32(static_cast(i)); } - if (size_ == 0) return; + if (size_ == 0) + return; pos = exifData.findKey(ExifKey(std::string("Exif.") + group_ + ".ImageWidth")); if (pos != exifData.end() && pos->count() > 0) { @@ -728,7 +741,8 @@ namespace { height_ = pos->toUint32(); } - if (width_ == 0 || height_ == 0) return; + if (width_ == 0 || height_ == 0) + return; valid_ = true; } @@ -797,7 +811,7 @@ namespace { enforce(size_ <= static_cast(io.size()), kerCorruptedMetadata); DataBuf buf(size_); uint32_t idxBuf = 0; - for (long i = 0; i < sizes.count(); i++) { + for (size_t i = 0; i < sizes.count(); i++) { uint32_t offset = dataValue.toUint32(i); uint32_t size = sizes.toUint32(i); @@ -843,15 +857,20 @@ namespace { } auto imageDatum = xmpData.findKey(XmpKey("Xmp.xmp.Thumbnails[1]/" + prefix + ":image")); - if (imageDatum == xmpData.end()) return; + if (imageDatum == xmpData.end()) + return; auto formatDatum = xmpData.findKey(XmpKey("Xmp.xmp.Thumbnails[1]/" + prefix + ":format")); - if (formatDatum == xmpData.end()) return; + if (formatDatum == xmpData.end()) + return; auto widthDatum = xmpData.findKey(XmpKey("Xmp.xmp.Thumbnails[1]/" + prefix + ":width")); - if (widthDatum == xmpData.end()) return; + if (widthDatum == xmpData.end()) + return; auto heightDatum = xmpData.findKey(XmpKey("Xmp.xmp.Thumbnails[1]/" + prefix + ":height")); - if (heightDatum == xmpData.end()) return; + if (heightDatum == xmpData.end()) + return; - if (formatDatum->toString() != "JPEG") return; + if (formatDatum->toString() != "JPEG") + return; width_ = widthDatum->toUint32(); height_ = heightDatum->toUint32(); @@ -875,7 +894,8 @@ namespace { DataBuf LoaderXmpJpeg::getData() const { - if (!valid()) return DataBuf(); + if (!valid()) + return DataBuf(); return DataBuf(preview_.c_data(), preview_.size()); } @@ -937,11 +957,13 @@ namespace { if (decodeBase64Table[static_cast(src[srcPos])] != invalid) validSrcSize++; } - if (validSrcSize > ULONG_MAX / 3) return DataBuf(); // avoid integer overflow + if (validSrcSize > ULONG_MAX / 3) + return DataBuf(); // avoid integer overflow const unsigned long destSize = (validSrcSize * 3) / 4; // allocate dest buffer - if (destSize > LONG_MAX) return DataBuf(); // avoid integer overflow + if (destSize > LONG_MAX) + return DataBuf(); // avoid integer overflow DataBuf dest(static_cast(destSize)); // decode @@ -971,7 +993,7 @@ namespace { return DataBuf(); } const byte *imageData = src.c_data(colorTableSize); - const long imageDataSize = src.size() - colorTableSize; + const long imageDataSize = static_cast(src.size()) - colorTableSize; const bool rle = (imageDataSize >= 3 && imageData[0] == 'R' && imageData[1] == 'L' && imageData[2] == 'E'); std::string dest; for (long i = rle ? 3 : 0; i < imageDataSize;) { @@ -1005,7 +1027,7 @@ namespace { DataBuf makePnm(uint32_t width, uint32_t height, const DataBuf &rgb) { - const long expectedSize = static_cast(width) * static_cast(height) * 3L; + const size_t expectedSize = width * height * 3UL; if (rgb.size() != expectedSize) { #ifndef SUPPRESS_WARNINGS EXV_WARNING << "Invalid size of preview data. Expected " << expectedSize << " bytes, got " << rgb.size() << " bytes.\n"; @@ -1037,13 +1059,14 @@ namespace Exiv2 { PreviewImage& PreviewImage::operator=(const PreviewImage& rhs) { - if (this == &rhs) return *this; + if (this == &rhs) + return *this; properties_ = rhs.properties_; preview_ = DataBuf(rhs.pData(), rhs.size()); return *this; } - long PreviewImage::writeFile(const std::string& path) const + size_t PreviewImage::writeFile(const std::string& path) const { std::string name = path + extension(); // Todo: Creating a DataBuf here unnecessarily copies the memory @@ -1063,7 +1086,7 @@ namespace Exiv2 { uint32_t PreviewImage::size() const { - return preview_.size(); + return static_cast(preview_.size()); } std::string PreviewImage::mimeType() const @@ -1105,7 +1128,7 @@ namespace Exiv2 { if (loader && loader->readDimensions()) { PreviewProperties props = loader->getProperties(); DataBuf buf = loader->getData(); // #16 getPreviewImage() - props.size_ = buf.size(); // update the size + props.size_ = static_cast(buf.size()); // update the size list.push_back(props) ; } } diff --git a/src/psdimage.cpp b/src/psdimage.cpp index 6b509344..bca3c0af 100644 --- a/src/psdimage.cpp +++ b/src/psdimage.cpp @@ -146,7 +146,8 @@ namespace Exiv2 { // Ensure that this is the correct image type if (!isPsdType(*io_, false)) { - if (io_->error() || io_->eof()) throw Error(kerFailedToReadImageData); + if (io_->error() || io_->eof()) + throw Error(kerFailedToReadImageData); throw Error(kerNotAnImage, "Photoshop"); } clearMetadata(); @@ -248,8 +249,9 @@ namespace Exiv2 { { DataBuf rawIPTC(resourceSize); io_->read(rawIPTC.data(), rawIPTC.size()); - if (io_->error() || io_->eof()) throw Error(kerFailedToReadImageData); - if (IptcParser::decode(iptcData_, rawIPTC.c_data(), rawIPTC.size())) { + if (io_->error() || io_->eof()) + throw Error(kerFailedToReadImageData); + if (IptcParser::decode(iptcData_, rawIPTC.c_data(), static_cast(rawIPTC.size()))) { #ifndef SUPPRESS_WARNINGS EXV_WARNING << "Failed to decode IPTC metadata.\n"; #endif @@ -262,7 +264,8 @@ namespace Exiv2 { { DataBuf rawExif(resourceSize); io_->read(rawExif.data(), rawExif.size()); - if (io_->error() || io_->eof()) throw Error(kerFailedToReadImageData); + if (io_->error() || io_->eof()) + throw Error(kerFailedToReadImageData); ByteOrder bo = ExifParser::decode(exifData_, rawExif.c_data(), rawExif.size()); setByteOrder(bo); if (rawExif.size() > 0 && byteOrder() == invalidByteOrder) { @@ -278,7 +281,8 @@ namespace Exiv2 { { DataBuf xmpPacket(resourceSize); io_->read(xmpPacket.data(), xmpPacket.size()); - if (io_->error() || io_->eof()) throw Error(kerFailedToReadImageData); + if (io_->error() || io_->eof()) + throw Error(kerFailedToReadImageData); xmpPacket_.assign(xmpPacket.c_str(), xmpPacket.size()); if (!xmpPacket_.empty() && XmpParser::decode(xmpData_, xmpPacket_)) { #ifndef SUPPRESS_WARNINGS @@ -323,7 +327,8 @@ namespace Exiv2 { if (nativePreview.size_ > 0 && nativePreview.position_ >= 0) { io_->seek(static_cast(nativePreview.size_), BasicIo::cur); - if (io_->error() || io_->eof()) throw Error(kerFailedToReadImageData); + if (io_->error() || io_->eof()) + throw Error(kerFailedToReadImageData); if (format == 1) { nativePreview.filter_ = ""; @@ -360,8 +365,10 @@ namespace Exiv2 { void PsdImage::doWriteMetadata(BasicIo& outIo) { - if (!io_->isopen()) throw Error(kerInputDataReadFailed); - if (!outIo.isopen()) throw Error(kerImageWriteFailed); + if (!io_->isopen()) + throw Error(kerInputDataReadFailed); + if (!outIo.isopen()) + throw Error(kerImageWriteFailed); #ifdef EXIV2_DEBUG_MESSAGES std::cout << "Exiv2::PsdImage::doWriteMetadata: Writing PSD file " << io_->path() << "\n"; @@ -370,7 +377,8 @@ namespace Exiv2 { // Ensure that this is the correct image type if (!isPsdType(*io_, true)) { - if (io_->error() || io_->eof()) throw Error(kerInputDataReadFailed); + if (io_->error() || io_->eof()) + throw Error(kerInputDataReadFailed); throw Error(kerNoImageInInputData); } @@ -381,47 +389,54 @@ namespace Exiv2 { // Get Photoshop header from original file byte psd_head[26]; - if (io_->read(psd_head, 26) != 26) throw Error(kerNotAnImage, "Photoshop"); + if (io_->read(psd_head, 26) != 26) + throw Error(kerNotAnImage, "Photoshop"); // Write Photoshop header data out to new PSD file - if (outIo.write(psd_head, 26) != 26) throw Error(kerImageWriteFailed); + if (outIo.write(psd_head, 26) != 26) + throw Error(kerImageWriteFailed); // Read colorDataLength from original PSD - if (io_->read(buf, 4) != 4) throw Error(kerNotAnImage, "Photoshop"); + if (io_->read(buf, 4) != 4) + throw Error(kerNotAnImage, "Photoshop"); uint32_t colorDataLength = getULong(buf, bigEndian); // Write colorDataLength ul2Data(buf, colorDataLength, bigEndian); - if (outIo.write(buf, 4) != 4) throw Error(kerImageWriteFailed); + if (outIo.write(buf, 4) != 4) + throw Error(kerImageWriteFailed); #ifdef EXIV2_DEBUG_MESSAGES std::cerr << std::dec << "colorDataLength: " << colorDataLength << "\n"; #endif // Copy colorData - uint32_t readTotal = 0; + size_t readTotal = 0; while (readTotal < colorDataLength) { - long toRead = static_cast(colorDataLength - readTotal) < lbuf.size() - ? static_cast(colorDataLength - readTotal) - : lbuf.size(); + size_t toRead = (colorDataLength - readTotal) < lbuf.size() + ? static_cast(colorDataLength) - readTotal + : lbuf.size(); if (io_->read(lbuf.data(), toRead) != toRead) throw Error(kerNotAnImage, "Photoshop"); readTotal += toRead; if (outIo.write(lbuf.c_data(), toRead) != toRead) throw Error(kerImageWriteFailed); } - if (outIo.error()) throw Error(kerImageWriteFailed); + if (outIo.error()) + throw Error(kerImageWriteFailed); uint32_t resLenOffset = io_->tell(); // remember for later update // Read length of all resource blocks from original PSD - if (io_->read(buf, 4) != 4) throw Error(kerNotAnImage, "Photoshop"); + if (io_->read(buf, 4) != 4) + throw Error(kerNotAnImage, "Photoshop"); uint32_t oldResLength = getULong(buf, bigEndian); uint32_t newResLength = 0; // Write oldResLength (will be updated later) ul2Data(buf, oldResLength, bigEndian); - if (outIo.write(buf, 4) != 4) throw Error(kerImageWriteFailed); + if (outIo.write(buf, 4) != 4) + throw Error(kerImageWriteFailed); #ifdef EXIV2_DEBUG_MESSAGES std::cerr << std::dec << "oldResLength: " << oldResLength << "\n"; @@ -435,7 +450,8 @@ namespace Exiv2 { bool exifDone = false; bool xmpDone = false; while (oldResLength > 0) { - if (io_->read(buf, 8) != 8) throw Error(kerNotAnImage, "Photoshop"); + if (io_->read(buf, 8) != 8) + throw Error(kerNotAnImage, "Photoshop"); // read resource type and ID uint32_t resourceType = getULong(buf, bigEndian); @@ -451,11 +467,12 @@ namespace Exiv2 { // read rest of resource name, plus any padding DataBuf resName(256); - if ( io_->read(resName.data(), adjResourceNameLen) - != static_cast(adjResourceNameLen)) throw Error(kerNotAnImage, "Photoshop"); + if (io_->read(resName.data(), adjResourceNameLen) != adjResourceNameLen) + throw Error(kerNotAnImage, "Photoshop"); // read resource size (actual length w/o padding!) - if (io_->read(buf, 4) != 4) throw Error(kerNotAnImage, "Photoshop"); + if (io_->read(buf, 4) != 4) + throw Error(kerNotAnImage, "Photoshop"); uint32_t resourceSize = getULong(buf, bigEndian); uint32_t pResourceSize = (resourceSize + 1) & ~1; // padded resource size @@ -493,25 +510,30 @@ namespace Exiv2 { #endif // Copy resource block to new PSD file ul2Data(buf, resourceType, bigEndian); - if (outIo.write(buf, 4) != 4) throw Error(kerImageWriteFailed); + if (outIo.write(buf, 4) != 4) + throw Error(kerImageWriteFailed); us2Data(buf, resourceId, bigEndian); - if (outIo.write(buf, 2) != 2) throw Error(kerImageWriteFailed); + if (outIo.write(buf, 2) != 2) + throw Error(kerImageWriteFailed); // Write resource name as Pascal string buf[0] = resourceNameLength & 0x00ff; - if (outIo.write(buf, 1) != 1) throw Error(kerImageWriteFailed); + if (outIo.write(buf, 1) != 1) + throw Error(kerImageWriteFailed); buf[0] = resourceNameFirstChar; - if (outIo.write(buf, 1) != 1) throw Error(kerImageWriteFailed); - if ( outIo.write(resName.c_data(), adjResourceNameLen) - != static_cast(adjResourceNameLen)) throw Error(kerImageWriteFailed); + if (outIo.write(buf, 1) != 1) + throw Error(kerImageWriteFailed); + if (outIo.write(resName.c_data(), adjResourceNameLen) != static_cast(adjResourceNameLen)) + throw Error(kerImageWriteFailed); ul2Data(buf, resourceSize, bigEndian); - if (outIo.write(buf, 4) != 4) throw Error(kerImageWriteFailed); + if (outIo.write(buf, 4) != 4) + throw Error(kerImageWriteFailed); readTotal = 0; while (readTotal < pResourceSize) { /// \todo almost same code as in lines 403-410. Factor out & reuse! - long toRead = static_cast(pResourceSize - readTotal) < lbuf.size() + size_t toRead = (pResourceSize - readTotal) < lbuf.size() ? static_cast(pResourceSize - readTotal) - : lbuf.size(); + : static_cast(lbuf.size()); if (io_->read(lbuf.data(), toRead) != toRead) { throw Error(kerNotAnImage, "Photoshop"); } @@ -519,7 +541,8 @@ namespace Exiv2 { if (outIo.write(lbuf.c_data(), toRead) != toRead) throw Error(kerImageWriteFailed); } - if (outIo.error()) throw Error(kerImageWriteFailed); + if (outIo.error()) + throw Error(kerImageWriteFailed); newResLength += pResourceSize + adjResourceNameLen + 12; } @@ -548,11 +571,13 @@ namespace Exiv2 { io_->populateFakeData(); // Copy remaining data - long readSize = 0; + size_t readSize = 0; while ((readSize=io_->read(lbuf.data(), lbuf.size()))) { - if (outIo.write(lbuf.c_data(), readSize) != readSize) throw Error(kerImageWriteFailed); + if (outIo.write(lbuf.c_data(), readSize) != readSize) + throw Error(kerImageWriteFailed); } - if (outIo.error()) throw Error(kerImageWriteFailed); + if (outIo.error()) + throw Error(kerImageWriteFailed); // Update length of resources #ifdef EXIV2_DEBUG_MESSAGES @@ -560,7 +585,8 @@ namespace Exiv2 { #endif outIo.seek(resLenOffset, BasicIo::beg); ul2Data(buf, newResLength, bigEndian); - if (outIo.write(buf, 4) != 4) throw Error(kerImageWriteFailed); + if (outIo.write(buf, 4) != 4) + throw Error(kerImageWriteFailed); } // PsdImage::doWriteMetadata @@ -576,20 +602,26 @@ namespace Exiv2 { std::cerr << std::hex << "write: resourceId: " << kPhotoshopResourceID_IPTC_NAA << "\n"; std::cerr << std::dec << "Writing IPTC_NAA: size: " << rawIptc.size() << "\n"; #endif - if (out.write(reinterpret_cast(Photoshop::irbId_[0]), 4) != 4) throw Error(kerImageWriteFailed); + if (out.write(reinterpret_cast(Photoshop::irbId_[0]), 4) != 4) + throw Error(kerImageWriteFailed); us2Data(buf, kPhotoshopResourceID_IPTC_NAA, bigEndian); - if (out.write(buf, 2) != 2) throw Error(kerImageWriteFailed); + if (out.write(buf, 2) != 2) + throw Error(kerImageWriteFailed); us2Data(buf, 0, bigEndian); // NULL resource name - if (out.write(buf, 2) != 2) throw Error(kerImageWriteFailed); - ul2Data(buf, rawIptc.size(), bigEndian); - if (out.write(buf, 4) != 4) throw Error(kerImageWriteFailed); + if (out.write(buf, 2) != 2) + throw Error(kerImageWriteFailed); + ul2Data(buf, static_cast(rawIptc.size()), bigEndian); + if (out.write(buf, 4) != 4) + throw Error(kerImageWriteFailed); // Write encoded Iptc data - if (out.write(rawIptc.c_data(), rawIptc.size()) != rawIptc.size()) throw Error(kerImageWriteFailed); - resLength += rawIptc.size() + 12; + if (out.write(rawIptc.c_data(), rawIptc.size()) != rawIptc.size()) + throw Error(kerImageWriteFailed); + resLength += static_cast(rawIptc.size()) + 12; if (rawIptc.size() & 1) // even padding { buf[0] = 0; - if (out.write(buf, 1) != 1) throw Error(kerImageWriteFailed); + if (out.write(buf, 1) != 1) + throw Error(kerImageWriteFailed); resLength++; } } @@ -616,20 +648,26 @@ namespace Exiv2 { std::cerr << std::hex << "write: resourceId: " << kPhotoshopResourceID_ExifInfo << "\n"; std::cerr << std::dec << "Writing ExifInfo: size: " << blob.size() << "\n"; #endif - if (out.write(reinterpret_cast(Photoshop::irbId_[0]), 4) != 4) throw Error(kerImageWriteFailed); + if (out.write(reinterpret_cast(Photoshop::irbId_[0]), 4) != 4) + throw Error(kerImageWriteFailed); us2Data(buf, kPhotoshopResourceID_ExifInfo, bigEndian); - if (out.write(buf, 2) != 2) throw Error(kerImageWriteFailed); + if (out.write(buf, 2) != 2) + throw Error(kerImageWriteFailed); us2Data(buf, 0, bigEndian); // NULL resource name - if (out.write(buf, 2) != 2) throw Error(kerImageWriteFailed); + if (out.write(buf, 2) != 2) + throw Error(kerImageWriteFailed); ul2Data(buf, static_cast(blob.size()), bigEndian); - if (out.write(buf, 4) != 4) throw Error(kerImageWriteFailed); + if (out.write(buf, 4) != 4) + throw Error(kerImageWriteFailed); // Write encoded Exif data - if (out.write(&blob[0], static_cast(blob.size())) != static_cast(blob.size())) throw Error(kerImageWriteFailed); + if (out.write(&blob[0], blob.size()) != blob.size()) + throw Error(kerImageWriteFailed); resLength += static_cast(blob.size()) + 12; if (blob.size() & 1) // even padding { buf[0] = 0; - if (out.write(buf, 1) != 1) throw Error(kerImageWriteFailed); + if (out.write(buf, 1) != 1) + throw Error(kerImageWriteFailed); resLength++; } } @@ -660,22 +698,28 @@ namespace Exiv2 { std::cerr << std::hex << "write: resourceId: " << kPhotoshopResourceID_XMPPacket << "\n"; std::cerr << std::dec << "Writing XMPPacket: size: " << xmpPacket.size() << "\n"; #endif - if (out.write(reinterpret_cast(Photoshop::irbId_[0]), 4) != 4) throw Error(kerImageWriteFailed); + if (out.write(reinterpret_cast(Photoshop::irbId_[0]), 4) != 4) + throw Error(kerImageWriteFailed); us2Data(buf, kPhotoshopResourceID_XMPPacket, bigEndian); - if (out.write(buf, 2) != 2) throw Error(kerImageWriteFailed); + if (out.write(buf, 2) != 2) + throw Error(kerImageWriteFailed); us2Data(buf, 0, bigEndian); // NULL resource name - if (out.write(buf, 2) != 2) throw Error(kerImageWriteFailed); + if (out.write(buf, 2) != 2) + throw Error(kerImageWriteFailed); ul2Data(buf, static_cast(xmpPacket.size()), bigEndian); - if (out.write(buf, 4) != 4) throw Error(kerImageWriteFailed); + if (out.write(buf, 4) != 4) + throw Error(kerImageWriteFailed); // Write XMPPacket - if (out.write(reinterpret_cast(xmpPacket.data()), static_cast(xmpPacket.size())) - != static_cast(xmpPacket.size())) throw Error(kerImageWriteFailed); - if (out.error()) throw Error(kerImageWriteFailed); + if (out.write(reinterpret_cast(xmpPacket.data()), xmpPacket.size()) != xmpPacket.size()) + throw Error(kerImageWriteFailed); + if (out.error()) + throw Error(kerImageWriteFailed); resLength += static_cast(xmpPacket.size()) + 12; if (xmpPacket.size() & 1) // even padding { buf[0] = 0; - if (out.write(buf, 1) != 1) throw Error(kerImageWriteFailed); + if (out.write(buf, 1) != 1) + throw Error(kerImageWriteFailed); resLength++; } } diff --git a/src/rafimage.cpp b/src/rafimage.cpp index 4dc9a2b1..732edf63 100644 --- a/src/rafimage.cpp +++ b/src/rafimage.cpp @@ -86,14 +86,15 @@ namespace Exiv2 { // not supported throw(Error(kerInvalidSettingForImage, "Image comment", "RAF")); } - + void RafImage::printStructure(std::ostream& out, PrintStructureOption option, int depth) { if (io_->open() != 0) { throw Error(kerDataSourceOpenFailed, io_->path(), strError()); } // Ensure this is the correct image type if (!isRafType(*io_, true)) { - if (io_->error() || io_->eof()) throw Error(kerFailedToReadImageData); + if (io_->error() || io_->eof()) + throw Error(kerFailedToReadImageData); throw Error(kerNotAnImage, "RAF"); } @@ -159,7 +160,7 @@ namespace Exiv2 { address = io_->tell(); DataBuf unknown(20); - io_->read(unknown.data(),unknown.size()); + io_->read(unknown.data(), unknown.size()); { out << Internal::indent(depth) << Internal::stringFormat(format,address, 20) @@ -286,21 +287,26 @@ namespace Exiv2 { #ifdef EXIV2_DEBUG_MESSAGES std::cerr << "Reading RAF file " << io_->path() << "\n"; #endif - if (io_->open() != 0) throw Error(kerDataSourceOpenFailed, io_->path(), strError()); + if (io_->open() != 0) + throw Error(kerDataSourceOpenFailed, io_->path(), strError()); IoCloser closer(*io_); // Ensure that this is the correct image type if (!isRafType(*io_, false)) { - if (io_->error() || io_->eof()) throw Error(kerFailedToReadImageData); + if (io_->error() || io_->eof()) + throw Error(kerFailedToReadImageData); throw Error(kerNotAnImage, "RAF"); } clearMetadata(); - if (io_->seek(84,BasicIo::beg) != 0) throw Error(kerFailedToReadImageData); + if (io_->seek(84,BasicIo::beg) != 0) + throw Error(kerFailedToReadImageData); byte jpg_img_offset [4]; - if (io_->read(jpg_img_offset, 4) != 4) throw Error(kerFailedToReadImageData); + if (io_->read(jpg_img_offset, 4) != 4) + throw Error(kerFailedToReadImageData); byte jpg_img_length [4]; - if (io_->read(jpg_img_length, 4) != 4) throw Error(kerFailedToReadImageData); + if (io_->read(jpg_img_length, 4) != 4) + throw Error(kerFailedToReadImageData); uint32_t jpg_img_off_u32 = Exiv2::getULong(jpg_img_offset, bigEndian); uint32_t jpg_img_len_u32 = Exiv2::getULong(jpg_img_length, bigEndian); @@ -319,9 +325,12 @@ namespace Exiv2 { enforce(jpg_img_len >= 12, kerCorruptedMetadata); DataBuf buf(jpg_img_len - 12); - if (io_->seek(jpg_img_off + 12,BasicIo::beg) != 0) throw Error(kerFailedToReadImageData); + if (io_->seek(jpg_img_off + 12,BasicIo::beg) != 0) + throw Error(kerFailedToReadImageData); + io_->read(buf.data(), buf.size()); - if (io_->error() || io_->eof()) throw Error(kerFailedToReadImageData); + if (io_->error() || io_->eof()) + throw Error(kerFailedToReadImageData); io_->seek(0,BasicIo::beg); // rewind @@ -329,7 +338,7 @@ namespace Exiv2 { iptcData_, xmpData_, buf.c_data(), - buf.size()); + static_cast(buf.size())); exifData_["Exif.Image2.JPEGInterchangeFormat"] = getULong(jpg_img_offset, bigEndian); exifData_["Exif.Image2.JPEGInterchangeFormatLength"] = getULong(jpg_img_length, bigEndian); @@ -338,22 +347,27 @@ namespace Exiv2 { // parse the tiff byte readBuff[4]; - if (io_->seek(100, BasicIo::beg) != 0) throw Error(kerFailedToReadImageData); - if (io_->read(readBuff, 4) != 4 ) throw Error(kerFailedToReadImageData); + if (io_->seek(100, BasicIo::beg) != 0) + throw Error(kerFailedToReadImageData); + if (io_->read(readBuff, 4) != 4 ) + throw Error(kerFailedToReadImageData); uint32_t tiffOffset = Exiv2::getULong(readBuff, bigEndian); - if (io_->read(readBuff, 4) != 4) throw Error(kerFailedToReadImageData); + if (io_->read(readBuff, 4) != 4) + throw Error(kerFailedToReadImageData); uint32_t tiffLength = Exiv2::getULong(readBuff, bigEndian); // sanity check. Does tiff lie inside the file? enforce(Safe::add(tiffOffset, tiffLength) <= io_->size(), kerCorruptedMetadata); - if (io_->seek(tiffOffset, BasicIo::beg) != 0) throw Error(kerFailedToReadImageData); + if (io_->seek(tiffOffset, BasicIo::beg) != 0) + throw Error(kerFailedToReadImageData); // Check if this really is a tiff and then call the tiff parser. // Check is needed because some older models just embed a raw bitstream. - // For those files we skip the parsing step. - if (io_->read(readBuff, 4) != 4) { throw Error(kerFailedToReadImageData); } + // For those files we skip the parsing step. + if (io_->read(readBuff, 4) != 4) { + throw Error(kerFailedToReadImageData); } io_->seek(-4, BasicIo::cur); if (memcmp(readBuff, "\x49\x49\x2A\x00", 4) == 0 || memcmp(readBuff, "\x4D\x4D\x00\x2A", 4) == 0) @@ -367,7 +381,7 @@ namespace Exiv2 { iptcData_, xmpData_, tiff.c_data(), - tiff.size()); + static_cast(tiff.size())); } } } // RafImage::readMetadata diff --git a/src/tags_int.cpp b/src/tags_int.cpp index f1259729..b1db3d3f 100644 --- a/src/tags_int.cpp +++ b/src/tags_int.cpp @@ -2601,7 +2601,7 @@ namespace Exiv2 { { uint16_t bit = 0; uint16_t comma = 0; - for (long i = 0; i < value.count(); i++ ) { // for each element in value array + for (size_t i = 0; i < value.count(); i++ ) { // for each element in value array auto bits = static_cast(value.toInt64(i)); for (uint16_t b = 0; b < 16; ++b) { // for every bit if (bits & (1 << b)) { @@ -2949,7 +2949,7 @@ namespace Exiv2 { std::ostream& print0x9101(std::ostream& os, const Value& value, const ExifData*) { - for (long i = 0; i < value.count(); ++i) { + for (size_t i = 0; i < value.count(); ++i) { const auto l = value.toInt64(i); switch (l) { case 0: break; diff --git a/src/tags_int.hpp b/src/tags_int.hpp index 8576de3f..b06a9bf1 100644 --- a/src/tags_int.hpp +++ b/src/tags_int.hpp @@ -344,7 +344,7 @@ namespace Exiv2 { return os; } - for (int i=0; i< value.count(); i++) { + for (size_t i=0; i< value.count(); i++) { if (i != 0) os << ", "; const TagVocabulary* td = find(array, value.toString(i)); diff --git a/src/tiffcomposite_int.cpp b/src/tiffcomposite_int.cpp index 983900fa..cd001550 100644 --- a/src/tiffcomposite_int.cpp +++ b/src/tiffcomposite_int.cpp @@ -56,14 +56,14 @@ namespace Exiv2 { && key.g_ == group_; } - IoWrapper::IoWrapper(BasicIo& io, const byte* pHeader, long size, OffsetWriter* pow) + IoWrapper::IoWrapper(BasicIo& io, const byte* pHeader, size_t size, OffsetWriter* pow) : io_(io), pHeader_(pHeader), size_(size), wroteHeader_(false), pow_(pow) { if (pHeader_ == nullptr || size_ == 0) wroteHeader_ = true; } - long IoWrapper::write(const byte* pData, long wcount) + size_t IoWrapper::write(const byte* pData, size_t wcount) { if (!wroteHeader_ && wcount > 0) { io_.write(pHeader_, size_); @@ -319,7 +319,7 @@ namespace Exiv2 { { storage_ = buf; pData_ = buf->data(); - size_ = buf->size(); + size_ = static_cast(buf->size()); } void TiffEntryBase::setData(byte* pData, uint32_t size, @@ -336,7 +336,7 @@ namespace Exiv2 { { if (value.get() == nullptr) return; - uint32_t newSize = value->size(); + size_t newSize = value->size(); if (newSize > size_) { setData(std::make_shared(newSize)); } @@ -392,14 +392,14 @@ namespace Exiv2 { return; } uint32_t size = 0; - for (long i = 0; i < pSize->count(); ++i) { + for (size_t i = 0; i < pSize->count(); ++i) { size += pSize->toUint32(i); } auto offset = pValue()->toUint32(0); // Todo: Remove limitation of JPEG writer: strips must be contiguous // Until then we check: last offset + last size - first offset == size? - if ( pValue()->toUint32(pValue()->count()-1) - + pSize->toUint32(pSize->count()-1) + if ( pValue()->toUint32(static_cast(pValue()->count())-1) + + pSize->toUint32(static_cast(pSize->count())-1) - offset != size) { #ifndef SUPPRESS_WARNINGS EXV_WARNING << "Directory " << groupName(group()) @@ -449,7 +449,7 @@ namespace Exiv2 { #endif return; } - for (long i = 0; i < pValue()->count(); ++i) { + for (size_t i = 0; i < pValue()->count(); ++i) { const auto offset = pValue()->toUint32(i); const byte* pStrip = pData + baseOffset + offset; const auto size = pSize->toUint32(i); @@ -525,7 +525,7 @@ namespace Exiv2 { uint32_t ArrayDef::size(uint16_t tag, IfdId group) const { TypeId typeId = toTypeId(tiffType_, tag, group); - return count_ * TypeInfo::typeSize(typeId); + return static_cast(count_ * TypeInfo::typeSize(typeId)); } bool TiffBinaryArray::initialize(IfdId group) @@ -985,7 +985,7 @@ namespace Exiv2 { uint32_t TiffEntryBase::doCount() const { - return count_; + return static_cast(count_); } uint32_t TiffMnEntry::doCount() const @@ -1019,7 +1019,7 @@ namespace Exiv2 { if (elements_.empty()) return 0; TypeId typeId = toTypeId(tiffType(), tag(), group()); - long typeSize = TypeInfo::typeSize(typeId); + size_t typeSize = TypeInfo::typeSize(typeId); if (0 == typeSize) { #ifndef SUPPRESS_WARNINGS EXV_WARNING << "Directory " << groupName(group()) @@ -1097,7 +1097,7 @@ namespace Exiv2 { } // Also add the size of data, but only if needed if (isRootDir) { - uint32_t sd = component->sizeData(); + uint32_t sd = static_cast(component->sizeData()); sd += sd & 1; // Align data to word boundary sizeData += sd; } @@ -1124,7 +1124,7 @@ namespace Exiv2 { sv += sv & 1; // Align value to word boundary valueIdx += sv; } - uint32_t sd = component->sizeData(); + uint32_t sd = static_cast(component->sizeData()); sd += sd & 1; // Align data to word boundary dataIdx += sd; } @@ -1154,7 +1154,7 @@ namespace Exiv2 { idx += sv; valueIdx += sv; } - uint32_t sd = component->sizeData(); + uint32_t sd = static_cast(component->sizeData()); sd += sd & 1; // Align data to word boundary dataIdx += sd; } @@ -1227,7 +1227,7 @@ namespace Exiv2 { DataBuf buf(pValue_->size()); pValue_->copy(buf.data(), byteOrder); ioWrapper.write(buf.c_data(), buf.size()); - return buf.size(); + return static_cast(buf.size()); } // TiffEntryBase::doWrite uint32_t TiffEntryBase::writeOffset(byte* buf, @@ -1260,7 +1260,8 @@ namespace Exiv2 { uint32_t dataIdx, uint32_t& /*imageIdx*/) { - if (!pValue() || pValue()->count() == 0) return 0; + if (!pValue() || pValue()->count() == 0) + return 0; DataBuf buf(pValue()->size()); uint32_t idx = 0; @@ -1274,7 +1275,7 @@ namespace Exiv2 { byteOrder); } ioWrapper.write(buf.c_data(), buf.size()); - return buf.size(); + return static_cast(buf.size()); } // TiffDataEntry::doWrite uint32_t TiffImageEntry::doWrite(IoWrapper& ioWrapper, @@ -1293,7 +1294,7 @@ namespace Exiv2 { << std::setfill('0') << std::hex << tag() << std::dec << ": Writing offset " << o2 << "\n"; #endif - DataBuf buf(static_cast(strips_.size()) * 4); + DataBuf buf(strips_.size() * 4); uint32_t idx = 0; for (auto&& strip : strips_) { idx += writeOffset(buf.data(idx), o2, tiffType(), byteOrder); @@ -1305,7 +1306,7 @@ namespace Exiv2 { } } ioWrapper.write(buf.c_data(), buf.size()); - return buf.size(); + return static_cast(buf.size()); } // TiffImageEntry::doWrite uint32_t TiffSubIfd::doWrite(IoWrapper& ioWrapper, @@ -1315,7 +1316,7 @@ namespace Exiv2 { uint32_t dataIdx, uint32_t& /*imageIdx*/) { - DataBuf buf(static_cast(ifds_.size()) * 4); + DataBuf buf(ifds_.size() * 4); uint32_t idx = 0; // Sort IFDs by group, needed if image data tags were copied first std::sort(ifds_.begin(), ifds_.end(), cmpGroupLt); @@ -1324,7 +1325,7 @@ namespace Exiv2 { dataIdx += ifd->size(); } ioWrapper.write(buf.c_data(), buf.size()); - return buf.size(); + return static_cast(buf.size()); } // TiffSubIfd::doWrite uint32_t TiffMnEntry::doWrite(IoWrapper& ioWrapper, @@ -1375,7 +1376,7 @@ namespace Exiv2 { // Some array entries need to have the size in the first element if (cfg()->hasSize_) { byte buf[4]; - long elSize = TypeInfo::typeSize(toTypeId(cfg()->elTiffType_, 0, cfg()->group_)); + size_t elSize = TypeInfo::typeSize(toTypeId(cfg()->elTiffType_, 0, cfg()->group_)); switch (elSize) { case 2: idx += us2Data(buf, size(), byteOrder); @@ -1415,7 +1416,7 @@ namespace Exiv2 { mio.write(buf.c_data(), buf.size()); } } - ioWrapper.write(mio.mmap(), static_cast(mio.size())); + ioWrapper.write(mio.mmap(), mio.size()); return idx; } // TiffBinaryArray::doWrite @@ -1428,11 +1429,12 @@ namespace Exiv2 { uint32_t& /*imageIdx*/) { Value const* pv = pValue(); - if (!pv || pv->count() == 0) return 0; + if (!pv || pv->count() == 0) + return 0; DataBuf buf(pv->size()); pv->copy(buf.data(), byteOrder); ioWrapper.write(buf.c_data(), buf.size()); - return buf.size(); + return static_cast(buf.size()); } // TiffBinaryElement::doWrite uint32_t TiffComponent::writeData(IoWrapper& ioWrapper, @@ -1492,9 +1494,10 @@ namespace Exiv2 { ioWrapper.write(buf.c_data(), buf.size()); // Align data to word boundary uint32_t align = (buf.size() & 1); - if (align) ioWrapper.putb(0x0); + if (align) + ioWrapper.putb(0x0); - return buf.size() + align; + return static_cast(buf.size() + align); } // TiffDataEntry::doWriteData uint32_t TiffSubIfd::doWriteData(IoWrapper& ioWrapper, @@ -1586,9 +1589,10 @@ namespace Exiv2 { uint32_t TiffImageEntry::doWriteImage(IoWrapper& ioWrapper, ByteOrder /*byteOrder*/) const { - if ( !pValue() ) throw Error(kerImageWriteFailed); // #1296 + if ( !pValue() ) + throw Error(kerImageWriteFailed); // #1296 - uint32_t len = pValue()->sizeDataArea(); + size_t len = pValue()->sizeDataArea(); if (len > 0) { #ifdef EXIV2_DEBUG_MESSAGES std::cerr << "TiffImageEntry, Directory " << groupName(group()) @@ -1598,8 +1602,9 @@ namespace Exiv2 { #endif DataBuf buf = pValue()->dataArea(); ioWrapper.write(buf.c_data(), buf.size()); - uint32_t align = len & 1; // Align image data to word boundary - if (align) ioWrapper.putb(0x0); + size_t align = len & 1; // Align image data to word boundary + if (align) + ioWrapper.putb(0x0); len += align; } else { @@ -1621,7 +1626,7 @@ namespace Exiv2 { #ifdef EXIV2_DEBUG_MESSAGES std::cerr << ", len = " << len << " bytes\n"; #endif - return len; + return static_cast(len); } // TiffImageEntry::doWriteImage uint32_t TiffComponent::size() const @@ -1641,7 +1646,7 @@ namespace Exiv2 { sv += sv & 1; // Align value to word boundary len += sv; } - uint32_t sd = component->sizeData(); + uint32_t sd = static_cast(component->sizeData()); sd += sd & 1; // Align data to word boundary len += sd; } @@ -1715,65 +1720,67 @@ namespace Exiv2 { uint32_t TiffBinaryElement::doSize() const { - if (!pValue()) return 0; - return pValue()->size(); - } // TiffBinaryElement::doSize + if (!pValue()) + return 0; + return static_cast(pValue()->size()); + } - uint32_t TiffComponent::sizeData() const + size_t TiffComponent::sizeData() const { return doSizeData(); - } // TiffComponent::sizeData + } - uint32_t TiffDirectory::doSizeData() const + size_t TiffDirectory::doSizeData() const { assert(false); return 0; - } // TiffDirectory::doSizeData + } - uint32_t TiffEntryBase::doSizeData() const + size_t TiffEntryBase::doSizeData() const { return 0; - } // TiffEntryBase::doSizeData + } - uint32_t TiffImageEntry::doSizeData() const + size_t TiffImageEntry::doSizeData() const { - uint32_t len = 0; + size_t len = 0; // For makernotes, TIFF image data is written to the data area if (group() > mnId) { // Todo: Fix this hack!! len = sizeImage(); } return len; - } // TiffImageEntry::doSizeData + } - uint32_t TiffDataEntry::doSizeData() const + size_t TiffDataEntry::doSizeData() const { - if (!pValue()) return 0; - return pValue()->sizeDataArea(); - } // TiffDataEntry::doSizeData + if (!pValue()) + return 0; + return static_cast(pValue()->sizeDataArea()); + } - uint32_t TiffSubIfd::doSizeData() const + size_t TiffSubIfd::doSizeData() const { uint32_t len = 0; for (auto&& ifd : ifds_) { len += ifd->size(); } return len; - } // TiffSubIfd::doSizeData + } - uint32_t TiffIfdMakernote::doSizeData() const + size_t TiffIfdMakernote::doSizeData() const { assert(false); return 0; - } // TiffIfdMakernote::doSizeData + } - uint32_t TiffComponent::sizeImage() const + size_t TiffComponent::sizeImage() const { return doSizeImage(); - } // TiffComponent::sizeImage + } - uint32_t TiffDirectory::doSizeImage() const + size_t TiffDirectory::doSizeImage() const { - uint32_t len = 0; + size_t len = 0; for (auto&& component : components_) { len += component->sizeImage(); } @@ -1781,31 +1788,32 @@ namespace Exiv2 { len += pNext_->sizeImage(); } return len; - } // TiffDirectory::doSizeImage + } - uint32_t TiffSubIfd::doSizeImage() const + size_t TiffSubIfd::doSizeImage() const { - uint32_t len = 0; + size_t len = 0; for (auto&& ifd : ifds_) { len += ifd->sizeImage(); } return len; } // TiffSubIfd::doSizeImage - uint32_t TiffIfdMakernote::doSizeImage() const + size_t TiffIfdMakernote::doSizeImage() const { return ifd_.sizeImage(); } // TiffIfdMakernote::doSizeImage - uint32_t TiffEntryBase::doSizeImage() const + size_t TiffEntryBase::doSizeImage() const { return 0; } // TiffEntryBase::doSizeImage - uint32_t TiffImageEntry::doSizeImage() const + size_t TiffImageEntry::doSizeImage() const { - if (!pValue()) return 0; - uint32_t len = pValue()->sizeDataArea(); + if (!pValue()) + return 0; + auto len = pValue()->sizeDataArea(); if (len == 0) { for (auto&& strip : strips_) { len += strip.second; @@ -1909,5 +1917,5 @@ namespace { } return 0; - } // fillGap + } } // namespace diff --git a/src/tiffcomposite_int.hpp b/src/tiffcomposite_int.hpp index 604b8b2c..410de70c 100644 --- a/src/tiffcomposite_int.hpp +++ b/src/tiffcomposite_int.hpp @@ -122,7 +122,7 @@ namespace Exiv2 { The IO wrapper owns none of the objects passed in so the caller is responsible to keep them alive. */ - IoWrapper(BasicIo& io, const byte* pHeader, long size, OffsetWriter* pow); + IoWrapper(BasicIo& io, const byte* pHeader, size_t size, OffsetWriter* pow); //@} //! @name Manipulators @@ -133,7 +133,7 @@ namespace Exiv2 { Writes the TIFF header to the IO, if it hasn't been written yet, followed by the data passed in the arguments. */ - long write(const byte* pData, long wcount); + size_t write(const byte* pData, size_t wcount); /*! @brief Wraps the corresponding BasicIo::putb() method. @@ -149,7 +149,7 @@ namespace Exiv2 { // DATA BasicIo& io_; //! Reference for the IO instance. const byte* pHeader_; //! Pointer to the header data. - long size_; //! Size of the header data. + size_t size_; //! Size of the header data. bool wroteHeader_; //! Indicates if the header has been written. OffsetWriter* pow_; //! Pointer to an offset-writer, if any, or 0 }; // class IoWrapper @@ -289,14 +289,14 @@ namespace Exiv2 { write(). Components derived from TiffEntryBase implement this method corresponding to their implementation of writeData(). */ - uint32_t sizeData() const; + size_t sizeData() const; /*! @brief Return the size in bytes of the image data of this component when written to a binary image. This is a support function for write(). TIFF components implement this method corresponding to their implementation of writeImage(). */ - uint32_t sizeImage() const; + size_t sizeImage() const; /*! @brief Return the unique id of the entry in the image. */ @@ -346,9 +346,9 @@ namespace Exiv2 { //! Implements count(). virtual uint32_t doCount() const =0; //! Implements sizeData(). - virtual uint32_t doSizeData() const =0; + virtual size_t doSizeData() const =0; //! Implements sizeImage(). - virtual uint32_t doSizeImage() const =0; + virtual size_t doSizeImage() const =0; //@} private: @@ -529,9 +529,9 @@ namespace Exiv2 { //! Implements size(). Return the size of a standard TIFF entry uint32_t doSize() const override; //! Implements sizeData(). Return 0. - uint32_t doSizeData() const override; + size_t doSizeData() const override; //! Implements sizeImage(). Return 0. - uint32_t doSizeImage() const override; + size_t doSizeImage() const override; //@} //! Helper function to write an \em offset to a preallocated binary buffer @@ -552,7 +552,7 @@ namespace Exiv2 { // DATA TiffType tiffType_; //!< Field TIFF type - uint32_t count_; //!< The number of values of the indicated type + size_t count_; //!< The number of values of the indicated type int64_t offset_; //!< Offset to the data area /*! Size of the data buffer holding the value in bytes, there is no @@ -717,7 +717,7 @@ namespace Exiv2 { // Using doWriteImage from base class // Using doSize() from base class //! Implements sizeData(). Return the size of the data area. - uint32_t doSizeData() const override; + size_t doSizeData() const override; // Using doSizeImage from base class //@} @@ -792,9 +792,9 @@ namespace Exiv2 { //! Implements size(). Return the size of the strip pointers. uint32_t doSize() const override; //! Implements sizeData(). Return the size of the image data area. - uint32_t doSizeData() const override; + size_t doSizeData() const override; //! Implements sizeImage(). Return the size of the image data area. - uint32_t doSizeImage() const override; + size_t doSizeImage() const override; //@} private: @@ -926,12 +926,12 @@ namespace Exiv2 { @brief This class does not really implement sizeData(), it only has size(). This method must not be called; it commits suicide. */ - uint32_t doSizeData() const override; + size_t doSizeData() const override; /*! @brief Implements sizeImage(). Return the sum of the image sizes of all components plus that of the next-IFD, if there is any. */ - uint32_t doSizeImage() const override; + size_t doSizeImage() const override; //@} private: @@ -1015,9 +1015,9 @@ namespace Exiv2 { //! Implements size(). Return the size of the sub-Ifd pointers. uint32_t doSize() const override; //! Implements sizeData(). Return the sum of the sizes of all sub-IFDs. - uint32_t doSizeData() const override; + size_t doSizeData() const override; //! Implements sizeImage(). Return the sum of the image sizes of all sub-IFDs. - uint32_t doSizeImage() const override; + size_t doSizeImage() const override; //@} private: @@ -1228,12 +1228,12 @@ namespace Exiv2 { @brief This class does not really implement sizeData(), it only has size(). This method must not be called; it commits suicide. */ - uint32_t doSizeData() const override; + size_t doSizeData() const override; /*! @brief Implements sizeImage(). Return the total image data size of the makernote IFD. */ - uint32_t doSizeImage() const override; + size_t doSizeImage() const override; //@} private: diff --git a/src/tiffimage.cpp b/src/tiffimage.cpp index 4353b5b3..8ae77520 100644 --- a/src/tiffimage.cpp +++ b/src/tiffimage.cpp @@ -194,7 +194,7 @@ namespace Exiv2 { Exiv2::ExifKey key("Exif.Image.InterColorProfile"); auto pos = exifData_.findKey(key); if ( pos != exifData_.end() ) { - long size = pos->count() * pos->typeSize(); + size_t size = pos->count() * pos->typeSize(); if (size == 0) { throw Error(kerFailedToReadImageData); } @@ -234,7 +234,7 @@ namespace Exiv2 { auto pos = exifData_.findKey(key); bool found = pos != exifData_.end(); if ( iccProfileDefined() ) { - Exiv2::DataValue value(iccProfile_.c_data(), iccProfile_.size()); + Exiv2::DataValue value(iccProfile_.c_data(), static_cast(iccProfile_.size())); if ( found ) pos->setValue(&value); else exifData_.add(key,&value); } else { @@ -247,12 +247,11 @@ namespace Exiv2 { TiffParser::encode(*io_, pData, size, bo, exifData_, iptcData_, xmpData_); // may throw } // TiffImage::writeMetadata - ByteOrder TiffParser::decode( - ExifData& exifData, + ByteOrder TiffParser::decode(ExifData& exifData, IptcData& iptcData, XmpData& xmpData, const byte* pData, - uint32_t size + size_t size ) { uint32_t root = Tag::root; @@ -269,7 +268,7 @@ namespace Exiv2 { iptcData, xmpData, pData, - size, + static_cast(size), root, TiffMapping::findDecoder); } // TiffParser::decode diff --git a/src/tiffimage_int.cpp b/src/tiffimage_int.cpp index e0eabf89..0e62964d 100644 --- a/src/tiffimage_int.cpp +++ b/src/tiffimage_int.cpp @@ -50,7 +50,7 @@ namespace Exiv2 { false, // Don't concatenate gaps { 0, ttUnsignedShort, 1 } }; - + //! Canon Camera Settings binary array - definition constexpr ArrayDef canonCsDef[] = { { 46, ttUnsignedShort, 3 } // Exif.CanonCs.Lens @@ -259,7 +259,7 @@ namespace Exiv2 { { 0, ttSignedLong, 1 } }; - + //! Canon RawBurst Info binary array - configuration @@ -1303,13 +1303,13 @@ namespace Exiv2 { { Tag::root, fujiId, exifId, 0x927c }, { Tag::root, canonId, exifId, 0x927c }, { Tag::root, canonCsId, canonId, 0x0001 }, - { Tag::root, canonSiId, canonId, 0x0004 }, + { Tag::root, canonSiId, canonId, 0x0004 }, { Tag::root, canonPaId, canonId, 0x0005 }, { Tag::root, canonCfId, canonId, 0x000f }, { Tag::root, canonPiId, canonId, 0x0012 }, { Tag::root, canonTiId, canonId, 0x0035 }, { Tag::root, canonFiId, canonId, 0x0093 }, - { Tag::root, canonPrId, canonId, 0x00a0 }, + { Tag::root, canonPrId, canonId, 0x00a0 }, { Tag::root, canonAfMiAdjId, canonId, 0x4013 }, { Tag::root, canonVigCor2Id, canonId, 0x4016 }, { Tag::root, canonLiOpId, canonId, 0x4018 }, @@ -1676,7 +1676,7 @@ namespace Exiv2 { { 0x0012, canonId, EXV_SIMPLE_BINARY_ARRAY(canonPiCfg) }, { 0x0035, canonId, EXV_SIMPLE_BINARY_ARRAY(canonTiCfg) }, { 0x0093, canonId, EXV_BINARY_ARRAY(canonFiCfg, canonFiDef) }, - { 0x00a0, canonId, EXV_SIMPLE_BINARY_ARRAY(canonPrCfg) }, + { 0x00a0, canonId, EXV_SIMPLE_BINARY_ARRAY(canonPrCfg) }, { 0x4013, canonId, EXV_SIMPLE_BINARY_ARRAY(canonAfMiAdjCfg) }, // { 0x4015, canonId, EXV_SIMPLE_BINARY_ARRAY(canonVigCorCfg) }, { 0x4016, canonId, EXV_SIMPLE_BINARY_ARRAY(canonVigCor2Cfg) }, @@ -1684,9 +1684,9 @@ namespace Exiv2 { { 0x4019, canonId, EXV_SIMPLE_BINARY_ARRAY(canonLeCfg) }, { 0x4020, canonId, EXV_SIMPLE_BINARY_ARRAY(canonAmCfg) }, { 0x4021, canonId, EXV_SIMPLE_BINARY_ARRAY(canonMeCfg) }, - { 0x4024, canonId, EXV_SIMPLE_BINARY_ARRAY(canonFilCfg) }, + { 0x4024, canonId, EXV_SIMPLE_BINARY_ARRAY(canonFilCfg) }, { 0x4025, canonId, EXV_SIMPLE_BINARY_ARRAY(canonHdrCfg) }, - { 0x4028, canonId, EXV_SIMPLE_BINARY_ARRAY(canonAfCCfg) }, + { 0x4028, canonId, EXV_SIMPLE_BINARY_ARRAY(canonAfCCfg) }, { 0x403f, canonId, EXV_SIMPLE_BINARY_ARRAY(canonRawBCfg) }, { Tag::next, canonId, ignoreTiffComponent }, { Tag::all, canonId, newTiffEntry }, @@ -2041,7 +2041,7 @@ namespace Exiv2 { group = ts->parentGroup_; } while (!(ts->root_ == root && ts->group_ == ifdIdNotSet)); - } // TiffCreator::getPath + } ByteOrder TiffParserWorker::decode( ExifData& exifData, diff --git a/src/tiffvisitor_int.cpp b/src/tiffvisitor_int.cpp index 575afe99..f4d4a7d5 100644 --- a/src/tiffvisitor_int.cpp +++ b/src/tiffvisitor_int.cpp @@ -427,8 +427,7 @@ namespace Exiv2 { byte const* record = nullptr; uint32_t sizeHdr = 0; uint32_t sizeData = 0; - if (0 != Photoshop::locateIptcIrb(pData, size, - &record, &sizeHdr, &sizeData)) { + if (0 != Photoshop::locateIptcIrb(pData, size, &record, &sizeHdr, &sizeData)) { return; } if (0 == IptcParser::decode(iptcData_, record + sizeHdr, sizeData)) { @@ -456,12 +455,13 @@ namespace Exiv2 { // create vector of signedShorts from unsignedShorts in Exif.Canon.AFInfo std::vector ints; std::vector uint; - for (long i = 0; i < object->pValue()->count(); i++) { + for (size_t i = 0; i < object->pValue()->count(); i++) { ints.push_back(static_cast(object->pValue()->toInt64(i))); uint.push_back(static_cast(object->pValue()->toInt64(i))); } // Check this is AFInfo2 (ints[0] = bytes in object) - if ( ints.at(0) != object->pValue()->count()*2 ) return ; + if ( ints.at(0) != static_cast(object->pValue()->count())*2 ) + return ; std::string familyGroup(std::string("Exif.") + groupName(object->group()) + "."); @@ -629,7 +629,7 @@ namespace Exiv2 { else { buf = std::move(rawIptc); // Note: This resets rawIptc } - value->read(buf.data(), buf.size(), byteOrder_); + value->read(buf.data(), static_cast(buf.size()), byteOrder_); Exifdatum iptcDatum(iptcNaaKey, value.get()); exifData_.add(iptcDatum); pos = exifData_.findKey(irbKey); // needed after add() @@ -643,7 +643,7 @@ namespace Exiv2 { exifData_.erase(pos); if (irbBuf.size() != 0) { auto value = Value::create(unsignedByte); - value->read(irbBuf.data(), irbBuf.size(), invalidByteOrder); + value->read(irbBuf.data(), static_cast(irbBuf.size()), invalidByteOrder); Exifdatum iptcDatum(irbKey, value.get()); exifData_.add(iptcDatum); } @@ -821,8 +821,10 @@ namespace Exiv2 { if (object->cfg() == nullptr || !object->decoded()) return; int32_t size = object->TiffEntryBase::doSize(); - if (size == 0) return; - if (!object->initialize(pRoot_)) return; + if (size == 0) + return; + if (!object->initialize(pRoot_)) + return; // Re-encrypt buffer if necessary CryptFct cryptFct = object->cfg()->cryptFct_; @@ -834,7 +836,7 @@ namespace Exiv2 { DataBuf buf = cryptFct(object->tag(), pData, size, pRoot_); if (buf.size() > 0) { pData = buf.c_data(); - size = buf.size(); + size = static_cast(buf.size()); } if (!object->updOrigDataBuf(pData, size)) { setDirty(); @@ -968,7 +970,7 @@ namespace Exiv2 { { encodeOffsetEntry(object, datum); - uint32_t sizeDataArea = object->pValue()->sizeDataArea(); + size_t sizeDataArea = object->pValue()->sizeDataArea(); if (sizeDataArea > 0 && writeMethod() == wmNonIntrusive) { #ifdef EXIV2_DEBUG_MESSAGES @@ -991,12 +993,12 @@ namespace Exiv2 { << " not found. Writing only one strip.\n"; #endif object->strips_.clear(); - object->strips_.emplace_back(zero, sizeDataArea); + object->strips_.emplace_back(zero, static_cast(sizeDataArea)); } else { uint32_t sizeTotal = 0; object->strips_.clear(); - for (long i = 0; i < pos->count(); ++i) { + for (size_t i = 0; i < pos->count(); ++i) { uint32_t len = pos->toUint32(i); object->strips_.emplace_back(zero, len); sizeTotal += len; @@ -1509,7 +1511,7 @@ namespace Exiv2 { p += 2; TiffType tiffType = getUShort(p, byteOrder()); TypeId typeId = toTypeId(tiffType, object->tag(), object->group()); - long typeSize = TypeInfo::typeSize(typeId); + size_t typeSize = TypeInfo::typeSize(typeId); if (0 == typeSize) { #ifndef SUPPRESS_WARNINGS EXV_WARNING << "Directory " << groupName(object->group()) @@ -1538,7 +1540,7 @@ namespace Exiv2 { if (count > std::numeric_limits::max() / typeSize) { throw Error(kerArithmeticOverflow); } - uint32_t size = typeSize * count; + uint32_t size = static_cast(typeSize * count); uint32_t offset = getLong(p, byteOrder()); byte* pData = p; if ( size > 4 diff --git a/src/types.cpp b/src/types.cpp index 7cc19277..15f59341 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -49,7 +49,7 @@ namespace { struct TypeInfoTable { Exiv2::TypeId typeId_; //!< Type id const char* name_; //!< Name of the type - long size_; //!< Bytes per data entry + size_t size_; //!< Bytes per data entry //! Comparison operator for \em typeId bool operator==(Exiv2::TypeId typeId) const { @@ -111,27 +111,28 @@ namespace Exiv2 { return tit->typeId_; } - long TypeInfo::typeSize(TypeId typeId) + size_t TypeInfo::typeSize(TypeId typeId) { const TypeInfoTable* tit = find(typeInfoTable, typeId); - if (!tit) return 0; + if (!tit) + return 0; return tit->size_; } - DataBuf::DataBuf(long size) : pData_(size) + DataBuf::DataBuf(size_t size) : pData_(size) {} - DataBuf::DataBuf(const byte* pData, long size) : pData_(size) + DataBuf::DataBuf(const byte* pData, size_t size) : pData_(size) { std::copy_n(pData, size, pData_.begin()); } - void DataBuf::alloc(long size) + void DataBuf::alloc(size_t size) { pData_.resize(size); } - void DataBuf::resize(long size) + void DataBuf::resize(size_t size) { pData_.resize(size); } @@ -213,18 +214,20 @@ namespace Exiv2 { } byte* Exiv2::DataBuf::data(size_t offset) { + /// \todo this first check should be for <= offset if (pData_.size() < offset) { throw std::overflow_error("Overflow in Exiv2::DataBuf::c_data"); - } else if (pData_.size() == 0 || pData_.size() == offset) { + } else if (pData_.empty() || pData_.size() == offset) { return nullptr; } return &pData_[offset]; } const byte* Exiv2::DataBuf::c_data(size_t offset) const { + /// \todo this first check should be for <= offset if (pData_.size() < offset) { throw std::overflow_error("Overflow in Exiv2::DataBuf::c_data"); - } else if (pData_.size() == 0 || pData_.size() == offset) { + } else if (pData_.empty() || pData_.size() == offset) { return nullptr; } return &pData_[offset]; @@ -240,7 +243,7 @@ namespace Exiv2 { static void checkDataBufBounds(const DataBuf& buf, size_t end) { enforce(end <= static_cast(std::numeric_limits::max()), "end of slice too large to be compared with DataBuf bounds."); - enforce(static_cast(end) <= buf.size(), "Invalid slice bounds specified"); + enforce(end <= buf.size(), "Invalid slice bounds specified"); } Slice makeSlice(DataBuf& buf, size_t begin, size_t end) diff --git a/src/value.cpp b/src/value.cpp index 5bc3687f..2d4fb20f 100644 --- a/src/value.cpp +++ b/src/value.cpp @@ -118,7 +118,7 @@ namespace Exiv2 { return value; } // Value::create - int Value::setDataArea(const byte* /*buf*/, long /*len*/) + int Value::setDataArea(const byte* /*buf*/, size_t /*len*/) { return -1; } @@ -131,12 +131,12 @@ namespace Exiv2 { return os.str(); } - std::string Value::toString(long /*n*/) const + std::string Value::toString(size_t /*n*/) const { return toString(); } - long Value::sizeDataArea() const + size_t Value::sizeDataArea() const { return 0; } @@ -158,12 +158,12 @@ namespace Exiv2 { read(buf, len, byteOrder); } - long DataValue::count() const + size_t DataValue::count() const { return size(); } - int DataValue::read(const byte* buf, long len, ByteOrder /*byteOrder*/) + int DataValue::read(const byte* buf, size_t len, ByteOrder /*byteOrder*/) { // byteOrder not needed value_.assign(buf, buf + len); @@ -190,9 +190,9 @@ namespace Exiv2 { return static_cast(std::copy(value_.begin(), value_.end(), buf) - buf); } - long DataValue::size() const + size_t DataValue::size() const { - return static_cast(value_.size()); + return value_.size(); } DataValue* DataValue::clone_() const @@ -210,7 +210,7 @@ namespace Exiv2 { return os; } - std::string DataValue::toString(long n) const + std::string DataValue::toString(size_t n) const { std::ostringstream os; os << static_cast(value_.at(n)); @@ -218,25 +218,25 @@ namespace Exiv2 { return os.str(); } - int64_t DataValue::toInt64(long n) const + int64_t DataValue::toInt64(size_t n) const { ok_ = true; return value_.at(n); } - uint32_t DataValue::toUint32(long n) const + uint32_t DataValue::toUint32(size_t n) const { ok_ = true; return value_.at(n); } - float DataValue::toFloat(long n) const + float DataValue::toFloat(size_t n) const { ok_ = true; return value_.at(n); } - Rational DataValue::toRational(long n) const + Rational DataValue::toRational(size_t n) const { ok_ = true; return {value_.at(n), 1}; @@ -267,7 +267,7 @@ namespace Exiv2 { return 0; } - int StringValueBase::read(const byte* buf, long len, ByteOrder /*byteOrder*/) + int StringValueBase::read(const byte* buf, size_t len, ByteOrder /*byteOrder*/) { // byteOrder not needed if (buf) value_ = std::string(reinterpret_cast(buf), len); @@ -285,14 +285,14 @@ namespace Exiv2 { ); } - long StringValueBase::count() const + size_t StringValueBase::count() const { return size(); } - long StringValueBase::size() const + size_t StringValueBase::size() const { - return static_cast(value_.size()); + return value_.size(); } std::ostream& StringValueBase::write(std::ostream& os) const @@ -300,25 +300,25 @@ namespace Exiv2 { return os << value_; } - int64_t StringValueBase::toInt64(long n) const + int64_t StringValueBase::toInt64(size_t n) const { ok_ = true; return value_.at(n); } - uint32_t StringValueBase::toUint32(long n) const + uint32_t StringValueBase::toUint32(size_t n) const { ok_ = true; return value_.at(n); } - float StringValueBase::toFloat(long n) const + float StringValueBase::toFloat(size_t n) const { ok_ = true; return value_.at(n); } - Rational StringValueBase::toRational(long n) const + Rational StringValueBase::toRational(size_t n) const { ok_ = true; return {value_.at(n), 1}; @@ -458,7 +458,7 @@ namespace Exiv2 { return StringValueBase::read(code + c); } - int CommentValue::read(const byte* buf, long len, ByteOrder byteOrder) + int CommentValue::read(const byte* buf, size_t len, ByteOrder byteOrder) { byteOrder_ = byteOrder; return StringValueBase::read(buf, len, byteOrder); @@ -601,19 +601,17 @@ namespace Exiv2 { return static_cast(s.size()); } - int XmpValue::read(const byte* buf, - long len, - ByteOrder /*byteOrder*/) + int XmpValue::read(const byte* buf, size_t len, ByteOrder /*byteOrder*/) { std::string s(reinterpret_cast(buf), len); return read(s); } - long XmpValue::size() const + size_t XmpValue::size() const { std::ostringstream os; write(os); - return static_cast(os.str().size()); + return os.str().size(); } XmpTextValue::XmpTextValue() @@ -667,12 +665,12 @@ namespace Exiv2 { return UniquePtr(clone_()); } - long XmpTextValue::size() const + size_t XmpTextValue::size() const { - return static_cast(value_.size()); + return value_.size(); } - long XmpTextValue::count() const + size_t XmpTextValue::count() const { return size(); } @@ -700,22 +698,22 @@ namespace Exiv2 { return os << value_; } - int64_t XmpTextValue::toInt64(long /*n*/) const + int64_t XmpTextValue::toInt64(size_t /*n*/) const { return parseInt64(value_, ok_); } - uint32_t XmpTextValue::toUint32(long /*n*/) const + uint32_t XmpTextValue::toUint32(size_t /*n*/) const { return parseUint32(value_, ok_); } - float XmpTextValue::toFloat(long /*n*/) const + float XmpTextValue::toFloat(size_t /*n*/) const { return parseFloat(value_, ok_); } - Rational XmpTextValue::toRational(long /*n*/) const + Rational XmpTextValue::toRational(size_t /*n*/) const { return parseRational(value_, ok_); } @@ -742,9 +740,9 @@ namespace Exiv2 { return UniquePtr(clone_()); } - long XmpArrayValue::count() const + size_t XmpArrayValue::count() const { - return static_cast(value_.size()); + return value_.size(); } std::ostream& XmpArrayValue::write(std::ostream& os) const @@ -756,28 +754,28 @@ namespace Exiv2 { return os; } - std::string XmpArrayValue::toString(long n) const + std::string XmpArrayValue::toString(size_t n) const { ok_ = true; return value_.at(n); } - int64_t XmpArrayValue::toInt64(long n) const + int64_t XmpArrayValue::toInt64(size_t n) const { return parseInt64(value_.at(n), ok_); } - uint32_t XmpArrayValue::toUint32(long n) const + uint32_t XmpArrayValue::toUint32(size_t n) const { return parseUint32(value_.at(n), ok_); } - float XmpArrayValue::toFloat(long n) const + float XmpArrayValue::toFloat(size_t n) const { return parseFloat(value_.at(n), ok_); } - Rational XmpArrayValue::toRational(long n) const + Rational XmpArrayValue::toRational(size_t n) const { return parseRational(value_.at(n), ok_); } @@ -846,9 +844,9 @@ namespace Exiv2 { return UniquePtr(clone_()); } - long LangAltValue::count() const + size_t LangAltValue::count() const { - return static_cast(value_.size()); + return value_.size(); } static const std::string x_default = "x-default"; @@ -875,7 +873,7 @@ namespace Exiv2 { return os; } - std::string LangAltValue::toString(long /*n*/) const + std::string LangAltValue::toString(size_t /*n*/) const { return toString(x_default); } @@ -891,25 +889,25 @@ namespace Exiv2 { return ""; } - int64_t LangAltValue::toInt64(long /*n*/) const + int64_t LangAltValue::toInt64(size_t /*n*/) const { ok_ = false; return 0; } - uint32_t LangAltValue::toUint32(long /*n*/) const + uint32_t LangAltValue::toUint32(size_t /*n*/) const { ok_ = false; return 0; } - float LangAltValue::toFloat(long /*n*/) const + float LangAltValue::toFloat(size_t /*n*/) const { ok_ = false; return 0.0F; } - Rational LangAltValue::toRational(long /*n*/) const + Rational LangAltValue::toRational(size_t /*n*/) const { ok_ = false; return {0, 0}; @@ -933,7 +931,7 @@ namespace Exiv2 { date_.day = day; } - int DateValue::read(const byte* buf, long len, ByteOrder /*byteOrder*/) + int DateValue::read(const byte* buf, size_t len, ByteOrder /*byteOrder*/) { const std::string str(reinterpret_cast(buf), len); return read(str); @@ -986,12 +984,12 @@ namespace Exiv2 { return date_; } - long DateValue::count() const + size_t DateValue::count() const { return size(); } - long DateValue::size() const + size_t DateValue::size() const { return 8; } @@ -1012,7 +1010,7 @@ namespace Exiv2 { return os; } - int64_t DateValue::toInt64(long /*n*/) const + int64_t DateValue::toInt64(size_t /*n*/) const { // Range of tm struct is limited to about 1970 to 2038 // This will return -1 if outside that range @@ -1026,7 +1024,7 @@ namespace Exiv2 { return l; } - uint32_t DateValue::toUint32(long /*n*/) const + uint32_t DateValue::toUint32(size_t /*n*/) const { const int64_t t = toInt64(); if (t < 0 || t > std::numeric_limits::max()) { @@ -1035,12 +1033,12 @@ namespace Exiv2 { return static_cast(t); } - float DateValue::toFloat(long n) const + float DateValue::toFloat(size_t n) const { return static_cast(toInt64(n)); } - Rational DateValue::toRational(long n) const + Rational DateValue::toRational(size_t n) const { return {static_cast(toInt64(n)), 1}; } @@ -1062,7 +1060,7 @@ namespace Exiv2 { time_.tzMinute = tzMinute; } - int TimeValue::read(const byte* buf, long len, ByteOrder /*byteOrder*/) + int TimeValue::read(const byte* buf, size_t len, ByteOrder /*byteOrder*/) { const std::string str(reinterpret_cast(buf), len); return read(str); @@ -1140,12 +1138,12 @@ namespace Exiv2 { return time_; } - long TimeValue::count() const + size_t TimeValue::count() const { return size(); } - long TimeValue::size() const + size_t TimeValue::size() const { return 11; } @@ -1174,7 +1172,7 @@ namespace Exiv2 { return os; } - int64_t TimeValue::toInt64(long /*n*/) const + int64_t TimeValue::toInt64(size_t /*n*/) const { // Returns number of seconds in the day in UTC. int64_t result = (time_.hour - time_.tzHour) * 60 * 60; @@ -1187,7 +1185,7 @@ namespace Exiv2 { return result; } - uint32_t TimeValue::toUint32(long /*n*/) const + uint32_t TimeValue::toUint32(size_t /*n*/) const { const int64_t t = toInt64(); if (t < 0 || t > std::numeric_limits::max()) { @@ -1196,12 +1194,12 @@ namespace Exiv2 { return static_cast(t); } - float TimeValue::toFloat(long n) const + float TimeValue::toFloat(size_t n) const { return static_cast(toInt64(n)); } - Rational TimeValue::toRational(long n) const + Rational TimeValue::toRational(size_t n) const { return {static_cast(toInt64(n)), 1}; } diff --git a/src/webpimage.cpp b/src/webpimage.cpp index 6562010f..7e25cbd3 100644 --- a/src/webpimage.cpp +++ b/src/webpimage.cpp @@ -411,7 +411,8 @@ namespace Exiv2 { WEBP_TAG_SIZE) throw Error(kerImageWriteFailed); ul2Data(data, static_cast(iccProfile_.size()), littleEndian); - if (outIo.write(data, WEBP_TAG_SIZE) != WEBP_TAG_SIZE) throw Error(kerImageWriteFailed); + if (outIo.write(data, WEBP_TAG_SIZE) != WEBP_TAG_SIZE) + throw Error(kerImageWriteFailed); if (outIo.write(iccProfile_.c_data(), iccProfile_.size()) != iccProfile_.size()) { throw Error(kerImageWriteFailed); } @@ -444,7 +445,7 @@ namespace Exiv2 { us2Data(data, static_cast(blob.size()) + 8, bigEndian); ul2Data(data, static_cast(blob.size()), littleEndian); if (outIo.write(data, WEBP_TAG_SIZE) != WEBP_TAG_SIZE) throw Error(kerImageWriteFailed); - if (outIo.write(&blob[0], static_cast(blob.size())) != static_cast(blob.size())) { + if (outIo.write(&blob[0], blob.size()) != blob.size()) { throw Error(kerImageWriteFailed); } if (outIo.tell() % 2) { @@ -457,8 +458,7 @@ namespace Exiv2 { throw Error(kerImageWriteFailed); ul2Data(data, static_cast(xmpPacket().size()), littleEndian); if (outIo.write(data, WEBP_TAG_SIZE) != WEBP_TAG_SIZE) throw Error(kerImageWriteFailed); - if (outIo.write(reinterpret_cast(xmp.data()), static_cast(xmp.size())) != - static_cast(xmp.size())) { + if (outIo.write(reinterpret_cast(xmp.data()), xmp.size()) != xmp.size()) { throw Error(kerImageWriteFailed); } if (outIo.tell() % 2) { @@ -526,7 +526,7 @@ namespace Exiv2 { if ( equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_EXIF) && option==kpsRecursive ) { // create memio object with the payload, then print the structure - MemIo p (payload.c_data(),payload.size()); + MemIo p (payload.c_data(), payload.size()); printTiffStructure(p,out,option,depth); } @@ -561,13 +561,11 @@ namespace Exiv2 { io_->readOrThrow(data, WEBP_TAG_SIZE * 3, Exiv2::kerCorruptedMetadata); - const uint32_t filesize_u32 = - Safe::add(Exiv2::getULong(data + WEBP_TAG_SIZE, littleEndian), 8U); + const uint32_t filesize_u32 = Safe::add(Exiv2::getULong(data + WEBP_TAG_SIZE, littleEndian), 8U); enforce(filesize_u32 <= io_->size(), Exiv2::kerCorruptedMetadata); // Check that `filesize_u32` is safe to cast to `long`. - enforce(filesize_u32 <= static_cast(std::numeric_limits::max()), - Exiv2::kerCorruptedMetadata); + enforce(filesize_u32 <= static_cast(std::numeric_limits::max()), Exiv2::kerCorruptedMetadata); WebPImage::decodeChunks(static_cast(filesize_u32)); @@ -591,8 +589,7 @@ namespace Exiv2 { const uint32_t size_u32 = Exiv2::getULong(size_buff, littleEndian); // Check that `size_u32` is safe to cast to `long`. - enforce(static_cast(size_u32) <= static_cast(std::numeric_limits::max()), - Exiv2::kerCorruptedMetadata); + enforce(size_u32 <= static_cast(std::numeric_limits::max()), Exiv2::kerCorruptedMetadata); const long size = static_cast(size_u32); // Check that `size` is within bounds. @@ -684,26 +681,26 @@ namespace Exiv2 { byte exifShortHeader[] = { 0x45, 0x78, 0x69, 0x66, 0x00, 0x00 }; byte exifTiffLEHeader[] = { 0x49, 0x49, 0x2A }; // "MM*" byte exifTiffBEHeader[] = { 0x4D, 0x4D, 0x00, 0x2A }; // "II\0*" - long offset = 0; + size_t offset = 0; bool s_header = false; bool le_header = false; bool be_header = false; - long pos = getHeaderOffset(payload.c_data(), payload.size(), reinterpret_cast(&exifLongHeader), 4); + long pos = getHeaderOffset(payload.c_data(), static_cast(payload.size()), reinterpret_cast(&exifLongHeader), 4); if (pos == -1) { - pos = getHeaderOffset(payload.c_data(), payload.size(), reinterpret_cast(&exifLongHeader), 6); + pos = getHeaderOffset(payload.c_data(), static_cast(payload.size()), reinterpret_cast(&exifLongHeader), 6); if (pos != -1) { s_header = true; } } if (pos == -1) { - pos = getHeaderOffset(payload.c_data(), payload.size(), reinterpret_cast(&exifTiffLEHeader), 3); + pos = getHeaderOffset(payload.c_data(), static_cast(payload.size()), reinterpret_cast(&exifTiffLEHeader), 3); if (pos != -1) { le_header = true; } } if (pos == -1) { - pos = getHeaderOffset(payload.c_data(), payload.size(), reinterpret_cast(&exifTiffBEHeader), 4); + pos = getHeaderOffset(payload.c_data(), static_cast(payload.size()), reinterpret_cast(&exifTiffBEHeader), 4); if (pos != -1) { be_header = true; } @@ -716,7 +713,7 @@ namespace Exiv2 { offset += 12; } - const long sizePayload = Safe::add(payload.size(), offset); + const size_t sizePayload = Safe::add(payload.size(), offset); DataBuf rawExifData(sizePayload); if (s_header) { @@ -871,7 +868,7 @@ namespace Exiv2 { /* Handle inject an icc profile right after VP8X chunk */ if (has_icc) { byte size_buff[WEBP_TAG_SIZE]; - ul2Data(size_buff, iccProfile_.size(), littleEndian); + ul2Data(size_buff, static_cast(iccProfile_.size()), littleEndian); if (iIo.write(reinterpret_cast(WEBP_CHUNK_HEADER_VP8X), WEBP_TAG_SIZE) != WEBP_TAG_SIZE) throw Error(kerImageWriteFailed); if (iIo.write(size_buff, WEBP_TAG_SIZE) != WEBP_TAG_SIZE) diff --git a/src/xmp.cpp b/src/xmp.cpp index c3baa081..630932ce 100644 --- a/src/xmp.cpp +++ b/src/xmp.cpp @@ -383,14 +383,14 @@ namespace Exiv2 { return 0; } - long Xmpdatum::count() const + size_t Xmpdatum::count() const { return p_->value_.get() == nullptr ? 0 : p_->value_->count(); } long Xmpdatum::size() const { - return p_->value_.get() == nullptr ? 0 : p_->value_->size(); + return p_->value_.get() == nullptr ? 0 : static_cast(p_->value_->size()); } std::string Xmpdatum::toString() const @@ -951,7 +951,7 @@ namespace Exiv2 { if (i.typeId() == xmpBag || i.typeId() == xmpSeq || i.typeId() == xmpAlt) { printNode(ns, i.tagName(), "", options); meta.SetProperty(ns.c_str(), i.tagName().c_str(), nullptr, options); - for (long idx = 0; idx < i.count(); ++idx) { + for (size_t idx = 0; idx < i.count(); ++idx) { const std::string item = i.tagName() + "[" + toString(idx + 1) + "]"; printNode(ns, item, i.toString(idx), 0); meta.SetProperty(ns.c_str(), item.c_str(), i.toString(idx).c_str()); diff --git a/src/xmpsidecar.cpp b/src/xmpsidecar.cpp index cb709a5c..7f292fda 100644 --- a/src/xmpsidecar.cpp +++ b/src/xmpsidecar.cpp @@ -79,18 +79,20 @@ namespace Exiv2 { IoCloser closer(*io_); // Ensure that this is the correct image type if (!isXmpType(*io_, false)) { - if (io_->error() || io_->eof()) throw Error(kerFailedToReadImageData); + if (io_->error() || io_->eof()) + throw Error(kerFailedToReadImageData); throw Error(kerNotAnImage, "XMP"); } // Read the XMP packet from the IO stream std::string xmpPacket; const long len = 64 * 1024; byte buf[len]; - long l; + size_t l; while ((l = io_->read(buf, len)) > 0) { xmpPacket.append(reinterpret_cast(buf), l); } - if (io_->error()) throw Error(kerFailedToReadImageData); + if (io_->error()) + throw Error(kerFailedToReadImageData); clearMetadata(); xmpPacket_ = xmpPacket; if (!xmpPacket_.empty() && XmpParser::decode(xmpData_, xmpPacket_)) { @@ -179,9 +181,8 @@ namespace Exiv2 { auto tempIo = std::make_unique(); // Write XMP packet - if ( tempIo->write(reinterpret_cast(xmpPacket_.data()), - static_cast(xmpPacket_.size())) - != static_cast(xmpPacket_.size())) throw Error(kerImageWriteFailed); + if (tempIo->write(reinterpret_cast(xmpPacket_.data()), xmpPacket_.size()) != xmpPacket_.size()) + throw Error(kerImageWriteFailed); if (tempIo->error()) throw Error(kerImageWriteFailed); io_->close(); io_->transfer(*tempIo); // may throw diff --git a/tests/bugfixes/github/test_CVE_2018_12265.py b/tests/bugfixes/github/test_CVE_2018_12265.py index 4ba11b46..0b73c73c 100644 --- a/tests/bugfixes/github/test_CVE_2018_12265.py +++ b/tests/bugfixes/github/test_CVE_2018_12265.py @@ -18,7 +18,6 @@ class AdditionOverflowInLoaderExifJpeg(metaclass=system_tests.CaseMeta): Warning: Directory Image, entry 0x0201: Strip 0 is outside of the data area; ignored. Warning: Directory Image, entry 0x0201: Strip 7 is outside of the data area; ignored. Error: Offset of directory Thumbnail, entry 0x0201 is out of bounds: Offset = 0x00000000; truncating the entry -$uncaught_exception $addition_overflow_message """ ] - retval = [1] + retval = [0] diff --git a/tests/bugfixes/github/test_issue_428.py b/tests/bugfixes/github/test_issue_428.py index e05086f9..b1b7de28 100644 --- a/tests/bugfixes/github/test_issue_428.py +++ b/tests/bugfixes/github/test_issue_428.py @@ -17,25 +17,22 @@ class PngReadRawProfile(metaclass=system_tests.CaseMeta): system_tests.path("$data_path/issue_428_poc4.png"), system_tests.path("$data_path/issue_428_poc5.png"), system_tests.path("$data_path/issue_428_poc8.png"), + system_tests.path("$data_path/issue_428_poc7.png"), system_tests.path("$data_path/issue_428_poc2.png"), system_tests.path("$data_path/issue_428_poc6.png"), - system_tests.path("$data_path/issue_428_poc7.png"), ] commands = ["$exiv2 " + fname for fname in filenames] stdout = [""] * len(filenames) - stderr = [ stderr_exception(fname) for fname in filenames[0:5] ] + stderr = [ stderr_exception(fname) for fname in filenames[0:6] ] - stderr.append("""$exiv2_exception_message """ + filenames[5] + """: + stderr.append("""$exiv2_exception_message """ + filenames[6] + """: $kerInputDataReadFailed """) stderr.append("""Error: XMP Toolkit error 201: Error in XMLValidator Warning: Failed to decode XMP metadata. -""" + stderr_exception(filenames[6])) - - stderr.append("""Warning: Failed to decode Exif metadata. """ + stderr_exception(filenames[7])) retval = [1] * len(filenames) diff --git a/unitTests/test_basicio.cpp b/unitTests/test_basicio.cpp index ad39d922..63129bfc 100644 --- a/unitTests/test_basicio.cpp +++ b/unitTests/test_basicio.cpp @@ -30,7 +30,7 @@ TEST(MemIo, isNotAtEofInitially) std::array buf; buf.fill(0); - MemIo io(buf.data(), static_cast(buf.size())); + MemIo io(buf.data(), buf.size()); ASSERT_FALSE(io.eof()); } @@ -39,7 +39,7 @@ TEST(MemIo, seekBeyondBufferSizeReturns1AndSetsEofToTrue) std::array buf; buf.fill(0); - MemIo io(buf.data(), static_cast(buf.size())); + MemIo io(buf.data(), buf.size()); ASSERT_EQ(1, io.seek(65, BasicIo::beg)); ASSERT_TRUE(io.eof()); } @@ -49,7 +49,7 @@ TEST(MemIo, seekBefore0Returns1ButItDoesNotSetEofToTrue) std::array buf; buf.fill(0); - MemIo io(buf.data(), static_cast(buf.size())); + MemIo io(buf.data(), buf.size()); ASSERT_EQ(1, io.seek(-1, BasicIo::beg)); ASSERT_FALSE(io.eof()); } @@ -59,7 +59,7 @@ TEST(MemIo, seekBeyondBoundsDoesNotMoveThePosition) std::array buf; buf.fill(0); - MemIo io(buf.data(), static_cast(buf.size())); + MemIo io(buf.data(), buf.size()); ASSERT_EQ(0, io.tell()); ASSERT_EQ(1, io.seek(65, BasicIo::beg)); ASSERT_EQ(0, io.tell()); @@ -70,7 +70,7 @@ TEST(MemIo, seekInsideBoundsMoveThePosition) std::array buf; buf.fill(0); - MemIo io(buf.data(), static_cast(buf.size())); + MemIo io(buf.data(), buf.size()); ASSERT_EQ(0, io.tell()); ASSERT_EQ(0, io.seek(32, BasicIo::beg)); ASSERT_EQ(32, io.tell()); @@ -81,7 +81,7 @@ TEST(MemIo, seekInsideBoundsUsingBeg_resetsThePosition) std::array buf; buf.fill(0); - MemIo io(buf.data(), static_cast(buf.size())); + MemIo io(buf.data(), buf.size()); std::vector positions {0, 8, 16, 32, 64}; for(auto pos: positions) { ASSERT_EQ(0, io.seek(pos, BasicIo::beg)); @@ -94,7 +94,7 @@ TEST(MemIo, seekInsideBoundsUsingCur_shiftThePosition) std::array buf; buf.fill(0); - MemIo io(buf.data(), static_cast(buf.size())); + MemIo io(buf.data(), buf.size()); std::vector shifts {4, 4, 8, 16, 32}; std::vector positions {4, 8, 16, 32, 64}; for (size_t i = 0; i < shifts.size(); ++i) { @@ -108,7 +108,7 @@ TEST(MemIo, seekToEndPosition_doesNotTriggerEof) std::array buf; buf.fill(0); - MemIo io(buf.data(), static_cast(buf.size())); + MemIo io(buf.data(), buf.size()); ASSERT_EQ(0, io.tell()); ASSERT_EQ(0, io.seek(0, BasicIo::end)); ASSERT_EQ(64, io.tell()); @@ -120,7 +120,7 @@ TEST(MemIo, seekToEndPositionAndReadTriggersEof) std::array buf; buf.fill(0); - MemIo io(buf.data(), static_cast(buf.size())); + MemIo io(buf.data(), buf.size()); ASSERT_EQ(0, io.seek(0, BasicIo::end)); ASSERT_EQ(64, io.tell()); @@ -134,7 +134,7 @@ TEST(MemIo, readEmptyIoReturns0) { std::array buf; MemIo io; - ASSERT_EQ(0, io.read(buf.data(), static_cast(buf.size()))); + ASSERT_EQ(0, io.read(buf.data(), buf.size())); } TEST(MemIo, readLessBytesThanAvailableReturnsRequestedBytes) @@ -143,7 +143,7 @@ TEST(MemIo, readLessBytesThanAvailableReturnsRequestedBytes) buf1.fill(1); buf2.fill(0); - MemIo io(buf1.data(), static_cast(buf1.size())); + MemIo io(buf1.data(), buf1.size()); ASSERT_EQ(5, io.read(buf2.data(), 5)); } @@ -153,7 +153,7 @@ TEST(MemIo, readSameBytesThanAvailableReturnsRequestedBytes) buf1.fill(1); buf2.fill(0); - MemIo io(buf1.data(), static_cast(buf1.size())); + MemIo io(buf1.data(), buf1.size()); ASSERT_EQ(10, io.read(buf2.data(), 10)); } @@ -163,6 +163,6 @@ TEST(MemIo, readMoreBytesThanAvailableReturnsAvailableBytes) buf1.fill(1); buf2.fill(0); - MemIo io(buf1.data(), static_cast(buf1.size())); + MemIo io(buf1.data(), buf1.size()); ASSERT_EQ(10, io.read(buf2.data(), 15)); } diff --git a/unitTests/test_futils.cpp b/unitTests/test_futils.cpp index 93bdfa20..fc225415 100644 --- a/unitTests/test_futils.cpp +++ b/unitTests/test_futils.cpp @@ -113,30 +113,26 @@ TEST(base64encode, encodesValidString) const std::string original ("This is a unit test"); const std::string expected ("VGhpcyBpcyBhIHVuaXQgdGVzdA=="); size_t encodeLength = ((original.size() + 2) / 3) * 4 + 1; - auto result = new char[encodeLength]; - ASSERT_EQ(1, base64encode(original.c_str(), original.size(), result, encodeLength)); - ASSERT_STREQ(expected.c_str(), result); - delete [] result; + std::vector result(encodeLength); + ASSERT_EQ(1, base64encode(original.c_str(), original.size(), result.data(), encodeLength)); + ASSERT_STREQ(expected.c_str(), result.data()); } TEST(base64encode, doesNotEncodeWithNotBigEnoughResultSize) { const std::string original ("This is a unit test"); size_t encodeLength = (original.size()); - auto result = new char[encodeLength]; - ASSERT_EQ(0, base64encode(original.c_str(), original.size(), result, encodeLength)); - delete [] result; + std::vector result(encodeLength); + ASSERT_EQ(0, base64encode(original.c_str(), original.size(), result.data(), encodeLength)); } TEST(base64decode, decodesValidString) { const std::string original ("VGhpcyBpcyBhIHVuaXQgdGVzdA=="); const std::string expected ("This is a unit test"); - auto result = new char[original.size()]; - ASSERT_EQ(static_cast(expected.size()), - base64decode(original.c_str(), result, original.size())); - ASSERT_STREQ(expected.c_str(), result); - delete [] result; + std::vector result(original.size()); + ASSERT_EQ(static_cast(expected.size()), base64decode(original.c_str(), result.data(), original.size())); + ASSERT_STREQ(expected.c_str(), result.data()); } TEST(AUri, parsesAndDecoreUrl) From f6b17d2a4d55af8b2adc7edbe7a2e44e65d3712b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= Date: Sun, 27 Feb 2022 10:40:27 +0100 Subject: [PATCH 16/19] Fix issues found by fuzzer --- src/helper_functions.cpp | 4 +++- src/jpgimage.cpp | 3 +-- src/pngchunk_int.cpp | 4 ++-- src/tiffvisitor_int.cpp | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/helper_functions.cpp b/src/helper_functions.cpp index e01a8bf2..074524b3 100644 --- a/src/helper_functions.cpp +++ b/src/helper_functions.cpp @@ -23,7 +23,9 @@ std::string string_from_unterminated(const char* data, size_t data_length) { + if (data_length == 0) { + return {}; + } const size_t StringLength = strnlen(data, data_length); - return std::string(data, StringLength); } diff --git a/src/jpgimage.cpp b/src/jpgimage.cpp index 16239c41..202fc005 100644 --- a/src/jpgimage.cpp +++ b/src/jpgimage.cpp @@ -621,8 +621,7 @@ namespace Exiv2 { assert(markerHasLength(marker)); assert(size >= 2); // Because this marker has a length field. // http://www.adobe.com/content/dam/Adobe/en/devnet/xmp/pdfs/XMPSpecificationPart3.pdf p75 - const std::string signature = - string_from_unterminated(buf.c_str(2), size - 2); + const std::string signature = string_from_unterminated(buf.c_str(2), size - 2); // 728 rmills@rmillsmbp:~/gnu/exiv2/ttt $ exiv2 -pS test/data/exiv2-bug922.jpg // STRUCTURE OF JPEG FILE: test/data/exiv2-bug922.jpg diff --git a/src/pngchunk_int.cpp b/src/pngchunk_int.cpp index ea787960..e31d5ce6 100644 --- a/src/pngchunk_int.cpp +++ b/src/pngchunk_int.cpp @@ -147,7 +147,7 @@ namespace Exiv2 arr = DataBuf(text, textsize); } else if (type == iTXt_Chunk) { - enforce(data.size() >= Safe::add(keysize, static_cast(3)), Exiv2::kerCorruptedMetadata); + enforce(data.size() > Safe::add(keysize, static_cast(3)), Exiv2::kerCorruptedMetadata); const size_t nullCount = std::count(data.c_data(keysize + 3), data.c_data(data.size()-1), '\0'); enforce(nullCount >= nullSeparators, Exiv2::kerCorruptedMetadata); @@ -524,7 +524,7 @@ namespace Exiv2 DataBuf PngChunk::readRawProfile(const DataBuf& text, bool iTXt) { - if (text.empty()) { + if (text.size() <= 1) { return DataBuf(); } diff --git a/src/tiffvisitor_int.cpp b/src/tiffvisitor_int.cpp index f4d4a7d5..07f6889f 100644 --- a/src/tiffvisitor_int.cpp +++ b/src/tiffvisitor_int.cpp @@ -999,7 +999,7 @@ namespace Exiv2 { uint32_t sizeTotal = 0; object->strips_.clear(); for (size_t i = 0; i < pos->count(); ++i) { - uint32_t len = pos->toUint32(i); + uint32_t len = pos->toUint32(static_cast(i)); object->strips_.emplace_back(zero, len); sizeTotal += len; } From 12738214f21beaf20423d8a9fd438c9096a7afa2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= Date: Sun, 27 Feb 2022 11:57:53 +0100 Subject: [PATCH 17/19] Fix warnings and place return statements separated from if --- src/convert.cpp | 144 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 95 insertions(+), 49 deletions(-) diff --git a/src/convert.cpp b/src/convert.cpp index 28af594a..77642c67 100644 --- a/src/convert.cpp +++ b/src/convert.cpp @@ -483,8 +483,10 @@ namespace Exiv2 { bool Converter::prepareExifTarget(const char* to, bool force) { auto pos = exifData_->findKey(ExifKey(to)); - if (pos == exifData_->end()) return true; - if (!overwrite_ && !force) return false; + if (pos == exifData_->end()) + return true; + if (!overwrite_ && !force) + return false; exifData_->erase(pos); return true; } @@ -492,8 +494,10 @@ namespace Exiv2 { bool Converter::prepareIptcTarget(const char* to, bool force) { auto pos = iptcData_->findKey(IptcKey(to)); - if (pos == iptcData_->end()) return true; - if (!overwrite_ && !force) return false; + if (pos == iptcData_->end()) + return true; + if (!overwrite_ && !force) + return false; while ((pos = iptcData_->findKey(IptcKey(to))) != iptcData_->end()) { iptcData_->erase(pos); } @@ -503,8 +507,10 @@ namespace Exiv2 { bool Converter::prepareXmpTarget(const char* to, bool force) { auto pos = xmpData_->findKey(XmpKey(to)); - if (pos == xmpData_->end()) return true; - if (!overwrite_ && !force) return false; + if (pos == xmpData_->end()) + return true; + if (!overwrite_ && !force) + return false; xmpData_->erase(pos); return true; } @@ -512,7 +518,8 @@ namespace Exiv2 { void Converter::cnvExifValue(const char* from, const char* to) { auto pos = exifData_->findKey(ExifKey(from)); - if (pos == exifData_->end()) return; + if (pos == exifData_->end()) + return; std::string value = pos->toString(); if (!pos->value().ok()) { #ifndef SUPPRESS_WARNINGS @@ -520,7 +527,8 @@ namespace Exiv2 { #endif return; } - if (!prepareXmpTarget(to)) return; + if (!prepareXmpTarget(to)) + return; (*xmpData_)[to] = value; if (erase_) exifData_->erase(pos); } @@ -528,8 +536,10 @@ namespace Exiv2 { void Converter::cnvExifComment(const char* from, const char* to) { auto pos = exifData_->findKey(ExifKey(from)); - if (pos == exifData_->end()) return; - if (!prepareXmpTarget(to)) return; + if (pos == exifData_->end()) + return; + if (!prepareXmpTarget(to)) + return; const auto cv = dynamic_cast(&pos->value()); if (cv == nullptr) { #ifndef SUPPRESS_WARNINGS @@ -545,10 +555,12 @@ namespace Exiv2 { void Converter::cnvExifArray(const char* from, const char* to) { auto pos = exifData_->findKey(ExifKey(from)); - if (pos == exifData_->end()) return; - if (!prepareXmpTarget(to)) return; + if (pos == exifData_->end()) + return; + if (!prepareXmpTarget(to)) + return; for (size_t i = 0; i < pos->count(); ++i) { - std::string value = pos->toString(i); + std::string value = pos->toString(static_cast(i)); if (!pos->value().ok()) { #ifndef SUPPRESS_WARNINGS EXV_WARNING << "Failed to convert " << from << " to " << to << "\n"; @@ -563,8 +575,10 @@ namespace Exiv2 { void Converter::cnvExifDate(const char* from, const char* to) { auto pos = exifData_->findKey(ExifKey(from)); - if (pos == exifData_->end()) return; - if (!prepareXmpTarget(to)) return; + if (pos == exifData_->end()) + return; + if (!prepareXmpTarget(to)) + return; int year=0, month=0, day=0, hour=0, min=0, sec=0; std::string subsec; char buf[30]; @@ -692,8 +706,10 @@ namespace Exiv2 { void Converter::cnvExifVersion(const char* from, const char* to) { auto pos = exifData_->findKey(ExifKey(from)); - if (pos == exifData_->end()) return; - if (!prepareXmpTarget(to)) return; + if (pos == exifData_->end()) + return; + if (!prepareXmpTarget(to)) + return; std::ostringstream value; for (size_t i = 0; i < pos->count(); ++i) { value << static_cast(pos->toInt64(i)); @@ -705,12 +721,14 @@ namespace Exiv2 { void Converter::cnvExifGPSVersion(const char* from, const char* to) { auto pos = exifData_->findKey(ExifKey(from)); - if (pos == exifData_->end()) return; - if (!prepareXmpTarget(to)) return; + if (pos == exifData_->end()) + return; + if (!prepareXmpTarget(to)) + return; std::ostringstream value; for (size_t i = 0; i < pos->count(); ++i) { if (i > 0) value << '.'; - value << pos->toInt64(i); + value << pos->toInt64(static_cast(i)); } (*xmpData_)[to] = value.str(); if (erase_) exifData_->erase(pos); @@ -719,8 +737,10 @@ namespace Exiv2 { void Converter::cnvExifFlash(const char* from, const char* to) { auto pos = exifData_->findKey(ExifKey(from)); - if (pos == exifData_->end() || pos->count() == 0) return; - if (!prepareXmpTarget(to)) return; + if (pos == exifData_->end() || pos->count() == 0) + return; + if (!prepareXmpTarget(to)) + return; auto value = pos->toInt64(); if (!pos->value().ok()) { #ifndef SUPPRESS_WARNINGS @@ -741,8 +761,10 @@ namespace Exiv2 { void Converter::cnvExifGPSCoord(const char* from, const char* to) { auto pos = exifData_->findKey(ExifKey(from)); - if (pos == exifData_->end()) return; - if (!prepareXmpTarget(to)) return; + if (pos == exifData_->end()) + return; + if (!prepareXmpTarget(to)) + return; if (pos->count() != 3) { #ifndef SUPPRESS_WARNINGS EXV_WARNING << "Failed to convert " << from << " to " << to << "\n"; @@ -785,8 +807,10 @@ namespace Exiv2 { void Converter::cnvXmpValue(const char* from, const char* to) { auto pos = xmpData_->findKey(XmpKey(from)); - if (pos == xmpData_->end()) return; - if (!prepareExifTarget(to)) return; + if (pos == xmpData_->end()) + return; + if (!prepareExifTarget(to)) + return; std::string value; if (!getTextValue(value, pos)) { #ifndef SUPPRESS_WARNINGS @@ -805,9 +829,11 @@ namespace Exiv2 { void Converter::cnvXmpComment(const char* from, const char* to) { - if (!prepareExifTarget(to)) return; + if (!prepareExifTarget(to)) + return; auto pos = xmpData_->findKey(XmpKey(from)); - if (pos == xmpData_->end()) return; + if (pos == xmpData_->end()) + return; std::string value; if (!getTextValue(value, pos)) { #ifndef SUPPRESS_WARNINGS @@ -822,12 +848,14 @@ namespace Exiv2 { void Converter::cnvXmpArray(const char* from, const char* to) { - if (!prepareExifTarget(to)) return; + if (!prepareExifTarget(to)) + return; auto pos = xmpData_->findKey(XmpKey(from)); - if (pos == xmpData_->end()) return; + if (pos == xmpData_->end()) + return; std::ostringstream array; for (size_t i = 0; i < pos->count(); ++i) { - std::string value = pos->toString(i); + std::string value = pos->toString(static_cast(i)); if (!pos->value().ok()) { #ifndef SUPPRESS_WARNINGS EXV_WARNING << "Failed to convert " << from << " to " << to << "\n"; @@ -846,8 +874,10 @@ namespace Exiv2 { void Converter::cnvXmpDate(const char* from, const char* to) { auto pos = xmpData_->findKey(XmpKey(from)); - if (pos == xmpData_->end()) return; - if (!prepareExifTarget(to)) return; + if (pos == xmpData_->end()) + return; + if (!prepareExifTarget(to)) + return; #ifdef EXV_HAVE_XMP_TOOLKIT std::string value = pos->toString(); if (!pos->value().ok()) { @@ -944,8 +974,10 @@ namespace Exiv2 { void Converter::cnvXmpVersion(const char* from, const char* to) { auto pos = xmpData_->findKey(XmpKey(from)); - if (pos == xmpData_->end()) return; - if (!prepareExifTarget(to)) return; + if (pos == xmpData_->end()) + return; + if (!prepareExifTarget(to)) + return; std::string value = pos->toString(); if (!pos->value().ok() || value.length() < 4) { #ifndef SUPPRESS_WARNINGS @@ -967,8 +999,10 @@ namespace Exiv2 { void Converter::cnvXmpGPSVersion(const char* from, const char* to) { auto pos = xmpData_->findKey(XmpKey(from)); - if (pos == xmpData_->end()) return; - if (!prepareExifTarget(to)) return; + if (pos == xmpData_->end()) + return; + if (!prepareExifTarget(to)) + return; std::string value = pos->toString(); if (!pos->value().ok()) { #ifndef SUPPRESS_WARNINGS @@ -986,8 +1020,10 @@ namespace Exiv2 { void Converter::cnvXmpFlash(const char* from, const char* to) { auto pos = xmpData_->findKey(XmpKey(std::string(from) + "/exif:Fired")); - if (pos == xmpData_->end()) return; - if (!prepareExifTarget(to)) return; + if (pos == xmpData_->end()) + return; + if (!prepareExifTarget(to)) + return; unsigned short value = 0; if (pos != xmpData_->end() && pos->count() > 0) { @@ -1049,8 +1085,10 @@ namespace Exiv2 { void Converter::cnvXmpGPSCoord(const char* from, const char* to) { auto pos = xmpData_->findKey(XmpKey(from)); - if (pos == xmpData_->end()) return; - if (!prepareExifTarget(to)) return; + if (pos == xmpData_->end()) + return; + if (!prepareExifTarget(to)) + return; std::string value = pos->toString(); if (!pos->value().ok()) { #ifndef SUPPRESS_WARNINGS @@ -1112,8 +1150,10 @@ namespace Exiv2 { void Converter::cnvIptcValue(const char* from, const char* to) { auto pos = iptcData_->findKey(IptcKey(from)); - if (pos == iptcData_->end()) return; - if (!prepareXmpTarget(to)) return; + if (pos == iptcData_->end()) + return; + if (!prepareXmpTarget(to)) + return; while (pos != iptcData_->end()) { if (pos->key() == from) { std::string value = pos->toString(); @@ -1138,8 +1178,10 @@ namespace Exiv2 { void Converter::cnvXmpValueToIptc(const char* from, const char* to) { auto pos = xmpData_->findKey(XmpKey(from)); - if (pos == xmpData_->end()) return; - if (!prepareIptcTarget(to)) return; + if (pos == xmpData_->end()) + return; + if (!prepareIptcTarget(to)) + return; if (pos->typeId() == langAlt || pos->typeId() == xmpText) { std::string value; @@ -1328,7 +1370,8 @@ namespace Exiv2 { bool convertStringCharset(std::string &str, const char* from, const char* to) { - if (0 == strcmp(from, to)) return true; // nothing to do + if (0 == strcmp(from, to)) + return true; // nothing to do bool ret = false; #if defined EXV_HAVE_ICONV ret = convertStringCharsetIconv(str, from, to); @@ -1370,7 +1413,8 @@ namespace { bool mb2wc(UINT cp, std::string& str) { - if (str.empty()) return true; + if (str.empty()) + return true; int len = MultiByteToWideChar(cp, 0, str.c_str(), (int)str.size(), 0, 0); if (len == 0) { #ifdef EXIV2_DEBUG_MESSAGES @@ -1393,7 +1437,8 @@ namespace { bool wc2mb(UINT cp, std::string& str) { - if (str.empty()) return true; + if (str.empty()) + return true; if (str.size() & 1) { #ifdef EXIV2_DEBUG_MESSAGES EXV_DEBUG << "wc2mb: Size " << str.size() << " of input string is not even.\n"; @@ -1508,7 +1553,8 @@ namespace { #if defined EXV_HAVE_ICONV bool convertStringCharsetIconv(std::string& str, const char* from, const char* to) { - if (0 == strcmp(from, to)) return true; // nothing to do + if (0 == strcmp(from, to)) + return true; // nothing to do bool ret = true; iconv_t cd; From e07c3771daeea18ba68bf05cf7e37b5c967997c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= Date: Sun, 27 Feb 2022 12:42:08 +0100 Subject: [PATCH 18/19] Fix more issues found by fuzzer --- src/bmffimage.cpp | 4 ++-- src/pngimage.cpp | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/bmffimage.cpp b/src/bmffimage.cpp index 41fb8d82..b361cffc 100644 --- a/src/bmffimage.cpp +++ b/src/bmffimage.cpp @@ -303,8 +303,8 @@ namespace Exiv2 std::string id; // Check that the string has a '\0' terminator. const char* str = data.c_str(skip); - const auto maxlen = static_cast(data.size() - skip); - enforce(strnlen(str, maxlen) < maxlen, Exiv2::kerCorruptedMetadata); + const size_t maxlen = data.size() - skip; + enforce(maxlen > 0 && strnlen(str, maxlen) < maxlen, Exiv2::kerCorruptedMetadata); std::string name(str); if (name.find("Exif") != std::string::npos) { // "Exif" or "ExifExif" exifID_ = ID; diff --git a/src/pngimage.cpp b/src/pngimage.cpp index 3db06f30..5dc0f9e3 100644 --- a/src/pngimage.cpp +++ b/src/pngimage.cpp @@ -701,14 +701,15 @@ namespace Exiv2 { } else if (!strcmp(szChunk, "tEXt") || !strcmp(szChunk, "zTXt") || !strcmp(szChunk, "iTXt") || !strcmp(szChunk, "iCCP")) { DataBuf key = PngChunk::keyTXTChunk(chunkBuf, true); - if (compare("Raw profile type exif", key, 21) || + if (key.empty() == false && ( + compare("Raw profile type exif", key, 21) || compare("Raw profile type APP1", key, 21) || compare("Raw profile type iptc", key, 21) || compare("Raw profile type xmp", key, 20) || compare("XML:com.adobe.xmp", key, 17) || compare("icc", key, 3) || // see test/data/imagemagick.png compare("ICC", key, 3) || - compare("Description", key, 11)) + compare("Description", key, 11))) { #ifdef EXIV2_DEBUG_MESSAGES std::cout << "Exiv2::PngImage::doWriteMetadata: strip " << szChunk From 208ec70df83cdbdf2525a46865b6be1ad259d731 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= Date: Sun, 27 Feb 2022 12:49:45 +0100 Subject: [PATCH 19/19] Fix windows builds --- app/actions.cpp | 3 ++- app/exiv2.cpp | 2 +- src/convert.cpp | 2 +- src/exif.cpp | 2 +- src/xmp.cpp | 4 ++-- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/app/actions.cpp b/app/actions.cpp index 114c860c..cf8f44d2 100644 --- a/app/actions.cpp +++ b/app/actions.cpp @@ -59,7 +59,8 @@ #ifdef EXV_HAVE_UNISTD_H # include // for stat() #endif -#ifdef _MSC_VER + +#if defined(_WIN32) || defined(__CYGWIN__) # include #include #include diff --git a/app/exiv2.cpp b/app/exiv2.cpp index 3a93bcb4..3e9518cb 100644 --- a/app/exiv2.cpp +++ b/app/exiv2.cpp @@ -39,7 +39,7 @@ #include #include -#if defined(_MSC_VER) +#if defined(_WIN32) || defined(__CYGWIN__) #include #include #include diff --git a/src/convert.cpp b/src/convert.cpp index 77642c67..af736b96 100644 --- a/src/convert.cpp +++ b/src/convert.cpp @@ -712,7 +712,7 @@ namespace Exiv2 { return; std::ostringstream value; for (size_t i = 0; i < pos->count(); ++i) { - value << static_cast(pos->toInt64(i)); + value << static_cast(pos->toInt64(static_cast(i))); } (*xmpData_)[to] = value.str(); if (erase_) exifData_->erase(pos); diff --git a/src/exif.cpp b/src/exif.cpp index 8df2f6b6..611eb449 100644 --- a/src/exif.cpp +++ b/src/exif.cpp @@ -869,7 +869,7 @@ namespace { { int64_t sum = 0; for (size_t i = 0; i < md.count(); ++i) { - sum += md.toInt64(i); + sum += md.toInt64(static_cast(i)); } return sum; } diff --git a/src/xmp.cpp b/src/xmp.cpp index 630932ce..741b39c7 100644 --- a/src/xmp.cpp +++ b/src/xmp.cpp @@ -953,8 +953,8 @@ namespace Exiv2 { meta.SetProperty(ns.c_str(), i.tagName().c_str(), nullptr, options); for (size_t idx = 0; idx < i.count(); ++idx) { const std::string item = i.tagName() + "[" + toString(idx + 1) + "]"; - printNode(ns, item, i.toString(idx), 0); - meta.SetProperty(ns.c_str(), item.c_str(), i.toString(idx).c_str()); + printNode(ns, item, i.toString(static_cast(idx)), 0); + meta.SetProperty(ns.c_str(), item.c_str(), i.toString(static_cast(idx)).c_str()); } continue; }