diff --git a/.github/workflows/on_push_BasicWinLinMac.yml b/.github/workflows/on_push_BasicWinLinMac.yml index 720cf010..bfd612f2 100644 --- a/.github/workflows/on_push_BasicWinLinMac.yml +++ b/.github/workflows/on_push_BasicWinLinMac.yml @@ -49,7 +49,7 @@ jobs: cmake --build . - - name: Unit Test + - name: Test run: | cd build ctest --output-on-failure @@ -80,7 +80,7 @@ jobs: cmake -GNinja -DEXIV2_ENABLE_WEBREADY=ON -DEXIV2_ENABLE_CURL=ON -DEXIV2_BUILD_UNIT_TESTS=ON -DEXIV2_ENABLE_BMFF=ON -DEXIV2_TEAM_WARNINGS_AS_ERRORS=ON -DCMAKE_INSTALL_PREFIX=install -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON .. cmake --build . - - name: Unit Test + - name: Test run: | cd build ctest --output-on-failure @@ -112,7 +112,7 @@ jobs: cmake -GNinja -DEXIV2_ENABLE_WEBREADY=ON -DEXIV2_ENABLE_CURL=ON -DEXIV2_BUILD_UNIT_TESTS=ON -DEXIV2_ENABLE_BMFF=ON -DEXIV2_TEAM_WARNINGS_AS_ERRORS=ON -DCMAKE_INSTALL_PREFIX=install -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DCMAKE_CXX_FLAGS="-Wno-deprecated-declarations" .. cmake --build . - - name: Unit Test + - name: Test run: | cd build ctest --output-on-failure diff --git a/CMakeLists.txt b/CMakeLists.txt index 410dad4d..9fe8b5f9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,5 @@ -cmake_minimum_required( VERSION 3.5.0 ) +# Minimum version imposed by Centos:8 +cmake_minimum_required( VERSION 3.11.0 ) project(exiv2 # use TWEAK to categorize the build VERSION 1.00.0.9 # 1.00.0 = GM (tagged and released) @@ -7,6 +8,7 @@ project(exiv2 # use TWEAK to categorize the build # 1.00.0.2 = RC2 (tagged and released) # 1.00.0.20 = RC2 Preview # 1.00.0.29 = RC2 Development + DESCRIPTION "Exif/IPTC/Xmp C++ metadata library and tools plus ICC Profiles, Previews and more." LANGUAGES CXX ) @@ -54,9 +56,7 @@ option( BUILD_WITH_CCACHE "Use ccache to speed up compilations" option( BUILD_WITH_COVERAGE "Add compiler flags to generate coverage stats" OFF ) include(cmake/gcovr.cmake REQUIRED) -set( PACKAGE_BUGREPORT "http://github.com/exiv2/exiv2" ) set( PACKAGE_URL "https://exiv2.org") -set( PROJECT_DESCRIPTION "Exif/IPTC/Xmp C++ metadata library and tools plus ICC Profiles, Previews and more.") if ( EXIV2_ENABLE_EXTERNAL_XMP ) set(EXIV2_ENABLE_XMP OFF) diff --git a/cmake/findDependencies.cmake b/cmake/findDependencies.cmake index 55e0f140..2527133f 100644 --- a/cmake/findDependencies.cmake +++ b/cmake/findDependencies.cmake @@ -18,9 +18,6 @@ if (APPLE) set(CMAKE_FIND_FRAMEWORK NEVER) endif() - -find_package(Threads REQUIRED) - if( EXIV2_ENABLE_PNG ) find_package( ZLIB REQUIRED ) endif( ) diff --git a/cmake/generateConfigFile.cmake b/cmake/generateConfigFile.cmake index 187a7474..9fc4e001 100644 --- a/cmake/generateConfigFile.cmake +++ b/cmake/generateConfigFile.cmake @@ -23,7 +23,6 @@ set(EXV_HAVE_ICONV ${ICONV_FOUND}) set(EXV_HAVE_LIBZ ${ZLIB_FOUND}) set(EXV_UNICODE_PATH ${EXIV2_ENABLE_WIN_UNICODE}) -check_cxx_symbol_exists(gmtime_r time.h EXV_HAVE_GMTIME_R) check_cxx_symbol_exists(mmap sys/mman.h EXV_HAVE_MMAP ) check_cxx_symbol_exists(munmap sys/mman.h EXV_HAVE_MUNMAP ) check_cxx_symbol_exists(strerror_r string.h EXV_HAVE_STRERROR_R ) diff --git a/contrib/vs2019/solution/exv_conf.h b/contrib/vs2019/solution/exv_conf.h index fafabd7b..fa10c3ad 100644 --- a/contrib/vs2019/solution/exv_conf.h +++ b/contrib/vs2019/solution/exv_conf.h @@ -12,9 +12,6 @@ // Define if you require PNG support. #define EXIV2_ENABLE_PNG -// Define if you have the `gmtime_r' function. -/* #undef EXV_HAVE_GMTIME_R */ - // Define if you have the header file. /* #undef EXV_HAVE_LIBINTL_H */ diff --git a/include/exiv2/basicio.hpp b/include/exiv2/basicio.hpp index b0169b23..1ae6c8bb 100644 --- a/include/exiv2/basicio.hpp +++ b/include/exiv2/basicio.hpp @@ -997,16 +997,11 @@ namespace Exiv2 { //@} protected: - //! @name Creators - //@{ - //! Default Constructor - RemoteIo() {p_=NULL;} - //@} // Pimpl idiom class Impl; //! Pointer to implementation - Impl* p_; + Impl* p_ {nullptr}; }; // class RemoteIo /*! @@ -1043,12 +1038,6 @@ namespace Exiv2 { HttpIo& operator=(const HttpIo& rhs); // Pimpl idiom class HttpImpl; - - //! @name Creators - //@{ - //! Default Destructor - virtual ~HttpIo(){} - //@} }; #ifdef EXV_USE_CURL @@ -1098,12 +1087,6 @@ namespace Exiv2 { CurlIo& operator=(const CurlIo& rhs); // Pimpl idiom class CurlImpl; - - //! @name Creators - //@{ - //! Default Destructor - virtual ~CurlIo(){} - //@} }; #endif diff --git a/include/exiv2/bmffimage.hpp b/include/exiv2/bmffimage.hpp index 2d08bd52..ff67e048 100644 --- a/include/exiv2/bmffimage.hpp +++ b/include/exiv2/bmffimage.hpp @@ -120,7 +120,7 @@ namespace Exiv2 int pixelHeight() const; //@} - Exiv2::ByteOrder endian_ ; + Exiv2::ByteOrder endian_{Exiv2::bigEndian}; private: void openOrThrow(); @@ -136,14 +136,14 @@ namespace Exiv2 return std::string(2*i,' '); } - uint32_t fileType_; + uint32_t fileType_{0}; std::set visits_; - uint64_t visits_max_; - uint16_t unknownID_; // 0xffff - uint16_t exifID_; - uint16_t xmpID_; + uint64_t visits_max_{0}; + uint16_t unknownID_{0xffff}; + uint16_t exifID_{0xffff}; + uint16_t xmpID_{0}; std::map ilocs_; - bool bReadMetadata_; + bool bReadMetadata_{false}; //@} /*! diff --git a/include/exiv2/tiffimage.hpp b/include/exiv2/tiffimage.hpp index 1e618d40..092fffaa 100644 --- a/include/exiv2/tiffimage.hpp +++ b/include/exiv2/tiffimage.hpp @@ -117,8 +117,8 @@ namespace Exiv2 { // DATA mutable std::string primaryGroup_; //!< The primary group mutable std::string mimeType_; //!< The MIME type - mutable int pixelWidth_; //!< Width of the primary image in pixels - mutable int pixelHeight_; //!< Height of the primary image in pixels + mutable int pixelWidthPrimary_; //!< Width of the primary image in pixels + mutable int pixelHeightPrimary_; //!< Height of the primary image in pixels }; // class TiffImage diff --git a/include/exiv2/types.hpp b/include/exiv2/types.hpp index 1e34bd23..7d23bd17 100644 --- a/include/exiv2/types.hpp +++ b/include/exiv2/types.hpp @@ -65,12 +65,6 @@ */ #define EXV_CALL_MEMBER_FN(object,ptrToMember) ((object).*(ptrToMember)) -// Simple min and max macros -//! Simple common min macro -#define EXV_MIN(a,b) ((a) < (b) ? (a) : (b)) -//! Simple common max macro -#define EXV_MAX(a,b) ((a) > (b) ? (a) : (b)) - #if defined(__GNUC__) && (__GNUC__ >= 4) || defined(__clang__) #define EXV_WARN_UNUSED_RESULT __attribute__ ((warn_unused_result)) #elif defined(_MSC_VER) && (_MSC_VER >= 1700) diff --git a/samples/geotag.cpp b/samples/geotag.cpp index 1b1093b3..c0d5f409 100644 --- a/samples/geotag.cpp +++ b/samples/geotag.cpp @@ -289,36 +289,26 @@ time_t Position::deltaMax_ = 60 ; /////////////////////////////////////////////////////////// // UserData - used by XML Parser -class UserData +struct UserData final { -public: - explicit UserData(Options& options): - indent(0) - , count(0) - , nTrkpt(0) - , bTime(false) - , bEle(false) - , ele(0.0) - , lat(0.0) - , lon(0.0) - , options_(options) + explicit UserData(Options& options) + : options_(options) {} - virtual ~UserData() = default; // public data members - int indent; - size_t count ; + int indent{0}; + size_t count{0}; Position now ; Position prev; - int nTrkpt; - bool bTime ; - bool bEle ; - double ele; - double lat; - double lon; + int nTrkpt{0}; + bool bTime{false}; + bool bEle{false}; + double ele{0.}; + double lat{0.}; + double lon{0.}; std::string xmlt; std::string exift; - time_t time; + time_t time{0}; Options& options_; // static public data memembers }; @@ -669,8 +659,8 @@ int readFile(const char* path, const Options& /* options */) if ( sina(ext,code) ) nResult = typeCode; } + fclose(f); } - if ( f ) fclose(f) ; return nResult ; } @@ -809,7 +799,7 @@ int main(int argc,const char* argv[]) shorts["-D"] = "-delta"; shorts["-s"] = "-delta"; shorts["-X"] = "-dryrun"; - shorts["-a"] = "-ascii"; + shorts["-A"] = "-ascii"; Options options ; options.help = sina(keywords[kwHELP ],argv) || argc < 2; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d6882e3b..c6c3f9e1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -215,7 +215,6 @@ if (NOT MSVC) target_link_libraries( exiv2lib PRIVATE psapi ws2_32 shell32 ) endif() - target_link_libraries( exiv2lib PRIVATE Threads::Threads) else() target_link_libraries( exiv2lib PRIVATE psapi ws2_32 shell32 ) endif() diff --git a/src/actions.cpp b/src/actions.cpp index 34738976..0c04e214 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -50,6 +50,7 @@ #include #include #include +#include #include #include // for stat() #include // for stat() @@ -71,6 +72,7 @@ // ***************************************************************************** // local declarations namespace { + std::mutex cs; //! Helper class to set the timestamp of a file to that of another file class Timestamp { @@ -253,7 +255,6 @@ namespace Action { try { path_ = path; int rc = 0; - Exiv2::PrintStructureOption option = Exiv2::kpsNone ; switch (Params::instance().printMode_) { case Params::pmSummary: rc = Params::instance().greps_.empty() ? printSummary() : printList(); break; case Params::pmList: rc = printList(); break; @@ -262,14 +263,10 @@ namespace Action { case Params::pmStructure: rc = printStructure(std::cout,Exiv2::kpsBasic, path_) ; break; case Params::pmRecursive: rc = printStructure(std::cout,Exiv2::kpsRecursive, path_) ; break; case Params::pmXMP: - if (option == Exiv2::kpsNone) - option = Exiv2::kpsXMP; - rc = setModeAndPrintStructure(option, path_,binary()); + rc = setModeAndPrintStructure(Exiv2::kpsXMP, path_,binary()); break; case Params::pmIccProfile: - if (option == Exiv2::kpsNone) - option = Exiv2::kpsIccProfile; - rc = setModeAndPrintStructure(option, path_,binary()); + rc = setModeAndPrintStructure(Exiv2::kpsIccProfile, path_,binary()); break; } return rc; @@ -540,8 +537,6 @@ namespace Action { bool first = true; if (Params::instance().printItems_ & Params::prTag) { - if (!first) - std::cout << " "; first = false; std::cout << "0x" << std::setw(4) << std::setfill('0') << std::right << std::hex << md.tag(); } @@ -1854,34 +1849,12 @@ namespace { return os.str(); } // tm2Str -// use static CS/MUTEX to make temporaryPath() thread safe -#if defined(_MSC_VER) || defined(__MINGW__) - static CRITICAL_SECTION cs; -#else - /* Unix/Linux/Cygwin/macOS */ - #include - /* This is the critical section object (statically allocated). */ - #if defined(__APPLE__) - #if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER) - static pthread_mutex_t cs = PTHREAD_RECURSIVE_MUTEX_INITIALIZER; - #else - static pthread_mutex_t cs = PTHREAD_MUTEX_INITIALIZER; - #endif - #else - #if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) - pthread_mutex_t cs = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; -#else - pthread_mutex_t cs = PTHREAD_MUTEX_INITIALIZER; -#endif -#endif -#endif - std::string temporaryPath() { static int count = 0; + std::lock_guard guard(cs); #if defined(_MSC_VER) || defined(__MINGW__) - EnterCriticalSection(&cs); char lpTempPathBuffer[MAX_PATH]; GetTempPath(MAX_PATH,lpTempPathBuffer); std::string tmp(lpTempPathBuffer); @@ -1890,22 +1863,14 @@ namespace { DWORD pid = ::GetProcessId(process); #else pid_t pid = ::getpid(); - pthread_mutex_lock( &cs ); std::string tmp = "/tmp/"; #endif - char sCount[13]; - sprintf(sCount,"_%d",++count); /// \todo replace by std::snprintf on master + std::string result = tmp + Exiv2::toString(pid) + "_" + std::to_string(count); + if (Exiv2::fileExists(result)) { + std::remove(result.c_str()); + } - std::string result = tmp + Exiv2::toString(pid) + sCount ; - if ( Exiv2::fileExists(result) ) std::remove(result.c_str()); - -#if defined(_MSC_VER) || defined(__MINGW__) - LeaveCriticalSection(&cs); -#else - pthread_mutex_unlock( &cs ); -#endif - - return result; + return result; } int metacopy(const std::string& source, diff --git a/src/actions.hpp b/src/actions.hpp index 3a5c1124..92c62bff 100644 --- a/src/actions.hpp +++ b/src/actions.hpp @@ -112,6 +112,10 @@ namespace Action { this method. */ static TaskFactory& instance(); + + //! Prevent copy construction: not implemented. + TaskFactory(const TaskFactory& rhs) = delete; + //! Destructor void cleanup(); @@ -144,8 +148,6 @@ namespace Action { private: //! Prevent construction other than through instance(). TaskFactory(); - //! Prevent copy construction: not implemented. - TaskFactory(const TaskFactory& rhs); //! Pointer to the one and only instance of this class. static TaskFactory* instance_; diff --git a/src/basicio.cpp b/src/basicio.cpp index 2bcca637..34e6c852 100644 --- a/src/basicio.cpp +++ b/src/basicio.cpp @@ -1047,7 +1047,7 @@ namespace Exiv2 { } //! Internal Pimpl structure of class MemIo. - class MemIo::Impl { + class MemIo::Impl final{ public: Impl() = default; //!< Default constructor Impl(const byte* data, long size); //!< Constructor 2 @@ -1088,10 +1088,7 @@ namespace Exiv2 { //! Destructor. Releases all managed memory. ~BlockMap() { - if (data_) { - std::free(data_); - data_ = nullptr; - } + delete [] data_; } //! @brief Populate the block. @@ -1099,8 +1096,9 @@ namespace Exiv2 { //! @param num The size of data void populate (byte* source, size_t num) { + assert(source != nullptr); size_ = num; - data_ = static_cast(std::malloc(size_)); + data_ = new byte [size_]; type_ = bMemory; std::memcpy(data_, source, size_); } @@ -1152,7 +1150,7 @@ namespace Exiv2 { if (!isMalloced_) { // Minimum size for 1st block - long size = EXV_MAX(blockSize * (1 + need / blockSize), size_); + long size = std::max(blockSize * (1 + need / blockSize), size_); auto data = static_cast(std::malloc(size)); if (data == nullptr) { throw Error(kerMallocFailed); @@ -1176,7 +1174,6 @@ namespace Exiv2 { throw Error(kerMallocFailed); } sizeAlloced_ = want; - isMalloced_ = true; } size_ = need; } @@ -1358,8 +1355,8 @@ namespace Exiv2 { long MemIo::read(byte* buf, long rcount) { - long avail = EXV_MAX(p_->size_ - p_->idx_, 0); - long allow = EXV_MIN(rcount, avail); + long avail = std::max(p_->size_ - p_->idx_, 0L); + long allow = std::min(rcount, avail); std::memcpy(buf, &p_->data_[p_->idx_], allow); p_->idx_ += allow; if (rcount > avail) p_->eof_ = true; @@ -1533,16 +1530,15 @@ namespace Exiv2 { } std::string data = orgPath.substr(base64Pos+7); - auto decodeData = new char[data.length()]; - long size = base64decode(data.c_str(), decodeData, data.length()); + std::vector decodeData (data.length()); + long size = base64decode(data.c_str(), decodeData.data(), data.length()); if (size > 0) { - fs.write(decodeData, size); + fs.write(decodeData.data(), size); fs.close(); } else { fs.close(); throw Error(kerErrorMessage, "Unable to decode base 64."); } - delete[] decodeData; } return path; @@ -1665,7 +1661,7 @@ namespace Exiv2 { size_t iBlock = (rcount == size_) ? 0 : lowBlock; while (remain) { - size_t allow = EXV_MIN(remain, blockSize_); + size_t allow = std::min(remain, blockSize_); blocksMap_[iBlock].populate(&source[totalRead], allow); remain -= allow; totalRead += allow; @@ -1704,7 +1700,7 @@ namespace Exiv2 { auto source = reinterpret_cast(const_cast(data.c_str())); size_t remain = p_->size_, iBlock = 0, totalRead = 0; while (remain) { - size_t allow = EXV_MIN(remain, p_->blockSize_); + size_t allow = std::min(remain, p_->blockSize_); p_->blocksMap_[iBlock].populate(&source[totalRead], allow); remain -= allow; totalRead += allow; @@ -1761,7 +1757,7 @@ namespace Exiv2 { size_t i = 0; size_t readCount = 0; size_t blockSize = 0; - auto buf = static_cast(std::malloc(p_->blockSize_)); + auto buf = new byte [p_->blockSize_]; size_t nBlocks = (p_->size_ + p_->blockSize_ - 1) / p_->blockSize_; // find $left @@ -1805,8 +1801,7 @@ namespace Exiv2 { blockSize = static_cast(p_->blocksMap_[blockIndex].getSize()); } - // free buf - if (buf) std::free(buf); + delete []buf; // submit to the remote machine. long dataSize = static_cast(src.size() - left - right); @@ -1840,7 +1835,7 @@ namespace Exiv2 { if (p_->eof_) return 0; p_->totalRead_ += rcount; - size_t allow = EXV_MIN(rcount, (long)( p_->size_ - p_->idx_)); + size_t allow = std::min(rcount, (long)( p_->size_ - p_->idx_)); size_t lowBlock = p_->idx_ /p_->blockSize_; size_t highBlock = (p_->idx_ + allow)/p_->blockSize_; @@ -1858,14 +1853,14 @@ namespace Exiv2 { byte* data = p_->blocksMap_[iBlock++].getData(); if (data == nullptr) data = fakeData; - size_t blockR = EXV_MIN(allow, p_->blockSize_ - startPos); + size_t blockR = std::min(allow, p_->blockSize_ - startPos); std::memcpy(&buf[totalRead], &data[startPos], blockR); totalRead += blockR; startPos = 0; allow -= blockR; } while(allow); - if (fakeData) std::free(fakeData); + std::free(fakeData); p_->idx_ += static_cast(totalRead); p_->eof_ = (p_->idx_ == static_cast(p_->size_)); diff --git a/src/bmffimage.cpp b/src/bmffimage.cpp index 43ed484d..d686997e 100644 --- a/src/bmffimage.cpp +++ b/src/bmffimage.cpp @@ -101,12 +101,8 @@ namespace Exiv2 } BmffImage::BmffImage(BasicIo::UniquePtr io, bool /* create */) - : Image(ImageType::bmff, mdExif | mdIptc | mdXmp, std::move(io)), - endian_(Exiv2::bigEndian), - bReadMetadata_(false) + : Image(ImageType::bmff, mdExif | mdIptc | mdXmp, std::move(io)) { - pixelWidth_ = 0; - pixelHeight_ = 0; } // BmffImage::BmffImage std::string BmffImage::toAscii(long n) @@ -292,10 +288,11 @@ namespace Exiv2 const auto maxlen = static_cast(data.size_ - skip); enforce(strnlen(str, maxlen) < maxlen, Exiv2::kerCorruptedMetadata); std::string name(str); - if ( !name.find("Exif") ) { // "Exif" or "ExifExif" + if (name.find("Exif") != std::string::npos) { // "Exif" or "ExifExif" exifID_ = ID; id=" *** Exif ***"; - } else if ( !name.find("mime\0xmp") || !name.find("mime\0application/rdf+xml") ) { + } else if (name.find("mime\0xmp") != std::string::npos || + name.find("mime\0application/rdf+xml") != std::string::npos) { xmpID_ = ID; id=" *** XMP ***"; } diff --git a/src/convert.cpp b/src/convert.cpp index dd3a2b0a..ee9dbf14 100644 --- a/src/convert.cpp +++ b/src/convert.cpp @@ -1088,7 +1088,7 @@ namespace Exiv2 { } if ( in.bad() || !(ref == 'N' || ref == 'S' || ref == 'E' || ref == 'W') - || sep1 != ',' || sep2 != ',' || !in.eof()) { + || sep1 != ',' || !in.eof()) { #ifndef SUPPRESS_WARNINGS EXV_WARNING << "Failed to convert " << from << " to " << to << "\n"; #endif diff --git a/src/crwimage_int.cpp b/src/crwimage_int.cpp index a78996a2..7a100320 100644 --- a/src/crwimage_int.cpp +++ b/src/crwimage_int.cpp @@ -645,12 +645,14 @@ namespace Exiv2 { UNUSED(rootDirectory); assert(rootDirectory == 0x0000); crwDirs.pop(); - if (!pRootDir_) pRootDir_ = new CiffDirectory; - if ( pRootDir_) { - CiffComponent* child = pRootDir_->add(crwDirs, crwTagId); - if ( child ) child->setValue(buf); + if (!pRootDir_) { + pRootDir_ = new CiffDirectory; } - } // CiffHeader::add + CiffComponent* child = pRootDir_->add(crwDirs, crwTagId); + if (child) { + child->setValue(buf); + } + } // CiffHeader::add CiffComponent* CiffComponent::add(CrwDirs& crwDirs, uint16_t crwTagId) { diff --git a/src/exiv2.cpp b/src/exiv2.cpp index 36bbb971..9f7c3995 100644 --- a/src/exiv2.cpp +++ b/src/exiv2.cpp @@ -956,26 +956,24 @@ int Params::nonoption(const std::string& argv) static int readFileToBuf(FILE* f,Exiv2::DataBuf& buf) { const int buff_size = 4*1028; - auto bytes = static_cast(::malloc(buff_size)); + std::vector bytes(buff_size); int nBytes = 0 ; - bool more = bytes != nullptr; + bool more {true}; while ( more ) { char buff[buff_size]; int n = static_cast(fread(buff, 1, buff_size, f)); more = n > 0 ; if ( more ) { - bytes = static_cast(realloc(bytes, nBytes + n)); - memcpy(bytes+nBytes,buff,n); + bytes.resize(nBytes+n); + memcpy(bytes.data()+nBytes,buff,n); nBytes += n ; } } if ( nBytes ) { buf.alloc(nBytes); - memcpy(buf.pData_, bytes, nBytes); + memcpy(buf.pData_, bytes.data(), nBytes); } - if (bytes != nullptr) - ::free(bytes); return nBytes; } @@ -1386,15 +1384,14 @@ namespace { // Skip empty lines and comments std::string::size_type cmdStart = line.find_first_not_of(delim); - if (cmdStart == std::string::npos || line[cmdStart] == '#') return false; + if (cmdStart == std::string::npos || line[cmdStart] == '#') + return false; // Get command and key std::string::size_type cmdEnd = line.find_first_of(delim, cmdStart+1); std::string::size_type keyStart = line.find_first_not_of(delim, cmdEnd+1); std::string::size_type keyEnd = line.find_first_of(delim, keyStart+1); - if ( cmdStart == std::string::npos - || cmdEnd == std::string::npos - || keyStart == std::string::npos) { + if (cmdEnd == std::string::npos || keyStart == std::string::npos) { std::string cmdLine ; #if defined(_MSC_VER) || defined(__MINGW__) for ( int i = 1 ; i < __argc ; i++ ) { cmdLine += std::string(" ") + formatArg(__argv[i]) ; } diff --git a/src/exiv2app.hpp b/src/exiv2app.hpp index 4381ab41..e765240a 100644 --- a/src/exiv2app.hpp +++ b/src/exiv2app.hpp @@ -158,6 +158,10 @@ public: @return Reference to the global Params instance. */ static Params& instance(); + + //! Prevent copy-construction: not implemented. + Params(const Params& rhs) = delete; + //! Destructor static void cleanup(); @@ -293,9 +297,6 @@ private: yodAdjust_[yodDay] = emptyYodAdjust_[yodDay]; } - //! Prevent copy-construction: not implemented. - Params(const Params& rhs); - //! Destructor, frees any allocated regexes in greps_ ~Params(); diff --git a/src/futils.cpp b/src/futils.cpp index a20ec184..7d756c0c 100644 --- a/src/futils.cpp +++ b/src/futils.cpp @@ -163,7 +163,7 @@ namespace Exiv2 { const auto data = static_cast(data_buf); for (size_t i = 0, j = 0 ; i < dataLength;) { - uint32_t octet_a = i < dataLength ? data[i++] : 0 ; + uint32_t octet_a = data[i++]; uint32_t octet_b = i < dataLength ? data[i++] : 0 ; uint32_t octet_c = i < dataLength ? data[i++] : 0 ; diff --git a/src/image.cpp b/src/image.cpp index 88a398ff..ee962217 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -335,12 +335,11 @@ namespace Exiv2 { } uint16_t dirLength = byteSwap2(dir,0,bSwap); - bool tooBig = dirLength > 500; - if ( tooBig ) throw Error(kerTiffDirectoryTooLarge); + if ( dirLength > 500 ) // tooBig + throw Error(kerTiffDirectoryTooLarge); if ( bFirst && bPrint ) { out << Internal::indent(depth) << Internal::stringFormat("STRUCTURE OF TIFF FILE (%c%c): ",c,c) << io.path() << std::endl; - if ( tooBig ) out << Internal::indent(depth) << "dirLength = " << dirLength << std::endl; } // Read the dictionary @@ -498,7 +497,7 @@ namespace Exiv2 { } if ( start ) { io.read(dir.pData_, 4); - start = tooBig ? 0 : byteSwap4(dir,0,bSwap); + start = byteSwap4(dir,0,bSwap); } } while (start) ; diff --git a/src/jpgimage.cpp b/src/jpgimage.cpp index 060651fc..f9e62708 100644 --- a/src/jpgimage.cpp +++ b/src/jpgimage.cpp @@ -332,8 +332,6 @@ namespace Exiv2 { // Markers can start with any number of 0xff while ((c=io_->getb()) == 0xff) { - if (c == EOF) - return -2; } return c; } diff --git a/src/pngimage.cpp b/src/pngimage.cpp index a9f78998..a6a039b6 100644 --- a/src/pngimage.cpp +++ b/src/pngimage.cpp @@ -57,6 +57,8 @@ const unsigned char pngBlank[] = { 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00, namespace { + const auto nullComp = (const Exiv2::byte*)"\0\0"; + const auto typeICCP = (const Exiv2::byte*)"iCCP"; inline bool compare(const char* str, const Exiv2::DataBuf& buf, size_t length) { assert(strlen(str) <= length); @@ -345,7 +347,7 @@ namespace Exiv2 { // format is content dependent if ( bGood ) { if ( bXMP ) { - while ( !data[start] && start < dataOffset) start++; // skip leading nul bytes + while (start < dataOffset && !data[start]) start++; // skip leading nul bytes out << data+start; // output the xmp } @@ -573,7 +575,7 @@ namespace Exiv2 { memcpy(chunkBuf.pData_, cheaderBuf.pData_, 8); // Copy header. bufRead = io_->read(chunkBuf.pData_ + 8, dataOffset + 4); // Extract chunk data + CRC if (io_->error()) throw Error(kerFailedToReadImageData); - if (bufRead != static_cast(dataOffset + 4)) + if (bufRead != static_cast(dataOffset) + 4L) throw Error(kerInputDataReadFailed); char szChunk[5]; @@ -645,8 +647,6 @@ namespace Exiv2 { if ( iccProfileDefined() ) { DataBuf compressed; if ( zlibToCompressed(iccProfile_.pData_,iccProfile_.size_,compressed) ) { - const auto nullComp = reinterpret_cast("\0\0"); - const auto type = reinterpret_cast("iCCP"); const auto nameLength = static_cast(profileName_.size()); const uint32_t chunkLength = nameLength + 2 + compressed.size_ ; byte length[4]; @@ -654,15 +654,15 @@ namespace Exiv2 { // calculate CRC uLong tmp = crc32(0L, Z_NULL, 0); - tmp = crc32(tmp, type, 4); - tmp = crc32(tmp, reinterpret_cast(profileName_.data()), nameLength); + tmp = crc32(tmp, typeICCP, 4); + tmp = crc32(tmp, (const Bytef*)profileName_.data(), nameLength); tmp = crc32(tmp, nullComp, 2); tmp = crc32(tmp, compressed.pData_, compressed.size_); byte crc[4]; ul2Data(crc, tmp, bigEndian); if( outIo.write(length, 4) != 4 - || outIo.write(type, 4) != 4 + || outIo.write(typeICCP, 4) != 4 || outIo.write(reinterpret_cast(profileName_.data()), nameLength) != nameLength || outIo.write(nullComp,2) != 2 || outIo.write (compressed.pData_,compressed.size_) != compressed.size_ diff --git a/src/preview.cpp b/src/preview.cpp index 558631a5..8d885672 100644 --- a/src/preview.cpp +++ b/src/preview.cpp @@ -1008,7 +1008,7 @@ namespace { DataBuf makePnm(uint32_t width, uint32_t height, const DataBuf &rgb) { - const long expectedSize = static_cast(width * height * 3); + const long expectedSize = static_cast(width) * static_cast(height) * 3L; if (rgb.size_ != expectedSize) { #ifndef SUPPRESS_WARNINGS EXV_WARNING << "Invalid size of preview data. Expected " << expectedSize << " bytes, got " << rgb.size_ << " bytes.\n"; diff --git a/src/tags_int.cpp b/src/tags_int.cpp index 9768aa9b..e4939dad 100644 --- a/src/tags_int.cpp +++ b/src/tags_int.cpp @@ -2512,8 +2512,8 @@ namespace Exiv2 { { const TagInfo* ti = tagList(ifdId); if (ti == nullptr) return nullptr; + if (tagName.empty()) return nullptr; const char* tn = tagName.c_str(); - if (tn == nullptr) return nullptr; for (int idx = 0; ti[idx].tag_ != 0xffff; ++idx) { if (0 == strcmp(ti[idx].name_, tn)) { return &ti[idx]; diff --git a/src/tiffcomposite_int.cpp b/src/tiffcomposite_int.cpp index 18c25b48..3e13493c 100644 --- a/src/tiffcomposite_int.cpp +++ b/src/tiffcomposite_int.cpp @@ -583,7 +583,7 @@ namespace Exiv2 { uint32_t TiffBinaryArray::addElement(uint32_t idx, const ArrayDef& def) { auto tag = static_cast(idx / cfg()->tagStep()); - int32_t sz = EXV_MIN(def.size(tag, cfg()->group_), TiffEntryBase::doSize() - idx); + int32_t sz = std::min(def.size(tag, cfg()->group_), TiffEntryBase::doSize() - idx); TiffComponent::UniquePtr tc = TiffCreator::create(tag, cfg()->group_); auto tp = dynamic_cast(tc.get()); // The assertion typically fails if a component is not configured in @@ -1698,7 +1698,7 @@ namespace Exiv2 { if (cfg()->hasFillers_ && def()) { const ArrayDef* lastDef = def() + defSize() - 1; auto lastTag = static_cast(lastDef->idx_ / cfg()->tagStep()); - idx = EXV_MAX(idx, lastDef->idx_ + lastDef->size(lastTag, cfg()->group_)); + idx = std::max(idx, lastDef->idx_ + lastDef->size(lastTag, cfg()->group_)); } return idx; diff --git a/src/tiffimage.cpp b/src/tiffimage.cpp index 60374064..e8cbfc9b 100644 --- a/src/tiffimage.cpp +++ b/src/tiffimage.cpp @@ -68,10 +68,11 @@ namespace Exiv2 { using namespace Internal; TiffImage::TiffImage(BasicIo::UniquePtr io, bool /*create*/) - : Image(ImageType::tiff, mdExif | mdIptc | mdXmp, std::move(io)), - pixelWidth_(0), pixelHeight_(0) + : Image(ImageType::tiff, mdExif | mdIptc | mdXmp, std::move(io)) + , pixelWidthPrimary_(0) + , pixelHeightPrimary_(0) { - } // TiffImage::TiffImage + } // TiffImage::TiffImage //! Structure for TIFF compression to MIME type mappings struct MimeTypeList { @@ -135,26 +136,30 @@ namespace Exiv2 { int TiffImage::pixelWidth() const { - if (pixelWidth_ != 0) return pixelWidth_; + if (pixelWidthPrimary_ != 0) { + return pixelWidthPrimary_; + } ExifKey key(std::string("Exif.") + primaryGroup() + std::string(".ImageWidth")); auto imageWidth = exifData_.findKey(key); if (imageWidth != exifData_.end() && imageWidth->count() > 0) { - pixelWidth_ = static_cast(imageWidth->toLong()); + pixelWidthPrimary_ = static_cast(imageWidth->toLong()); } - return pixelWidth_; + return pixelWidthPrimary_; } int TiffImage::pixelHeight() const { - if (pixelHeight_ != 0) return pixelHeight_; + if (pixelHeightPrimary_ != 0) { + return pixelHeightPrimary_; + } ExifKey key(std::string("Exif.") + primaryGroup() + std::string(".ImageLength")); auto imageHeight = exifData_.findKey(key); if (imageHeight != exifData_.end() && imageHeight->count() > 0) { - pixelHeight_ = imageHeight->toLong(); + pixelHeightPrimary_ = imageHeight->toLong(); } - return pixelHeight_; + return pixelHeightPrimary_; } void TiffImage::setComment(const std::string& /*comment*/) diff --git a/src/tiffvisitor_int.cpp b/src/tiffvisitor_int.cpp index a43592c4..063cd250 100644 --- a/src/tiffvisitor_int.cpp +++ b/src/tiffvisitor_int.cpp @@ -1597,10 +1597,8 @@ namespace Exiv2 { // #1143 Write a "hollow" buffer for the preview image // Sadly: we don't know the exact location of the image in the source (it's near offset) // And neither TiffReader nor TiffEntryBase have access to the BasicIo object being processed - auto buffer = static_cast(::malloc(isize)); - ::memset(buffer,0,isize); - v->read(buffer,isize, byteOrder()); - ::free(buffer); + std::vector buffer(isize); + v->read(buffer.data() ,isize, byteOrder()); } object->setValue(std::move(v)); diff --git a/src/webpimage.cpp b/src/webpimage.cpp index 643e64ce..647f8308 100644 --- a/src/webpimage.cpp +++ b/src/webpimage.cpp @@ -639,7 +639,6 @@ namespace Exiv2 { byte exifShortHeader[] = { 0x45, 0x78, 0x69, 0x66, 0x00, 0x00 }; byte exifTiffLEHeader[] = { 0x49, 0x49, 0x2A }; // "MM*" byte exifTiffBEHeader[] = { 0x4D, 0x4D, 0x00, 0x2A }; // "II\0*" - byte* rawExifData = nullptr; long offset = 0; bool s_header = false; bool le_header = false; @@ -673,7 +672,7 @@ namespace Exiv2 { } const long sizePayload = payload.size_ + offset; - rawExifData = static_cast(malloc(sizePayload)); + byte* rawExifData = new byte[sizePayload]; if (s_header) { us2Data(size_buff2, static_cast(sizePayload - 6), bigEndian); @@ -710,7 +709,7 @@ namespace Exiv2 { exifData_.clear(); } - if (rawExifData) free(rawExifData); + delete [] rawExifData; } else if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_XMP)) { readOrThrow(*io_, payload.pData_, payload.size_, Exiv2::kerCorruptedMetadata); xmpPacket_.assign(reinterpret_cast(payload.pData_), payload.size_);