diff --git a/.compat-exiv2-026.metadata b/.compat-exiv2-026.metadata new file mode 100644 index 0000000..7a1906f --- /dev/null +++ b/.compat-exiv2-026.metadata @@ -0,0 +1 @@ +b267149993f8637ab9d0782c9cd73a5c3092427b SOURCES/exiv2-0.26-trunk.tar.gz diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f144f3f --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/exiv2-0.26-trunk.tar.gz diff --git a/SOURCES/0006-1296-Fix-submitted.patch b/SOURCES/0006-1296-Fix-submitted.patch new file mode 100644 index 0000000..bc3c413 --- /dev/null +++ b/SOURCES/0006-1296-Fix-submitted.patch @@ -0,0 +1,25 @@ +From 2f8681e120d277e418941c4361c83b5028f67fd8 Mon Sep 17 00:00:00 2001 +From: clanmills +Date: Sat, 27 May 2017 10:18:17 +0100 +Subject: [PATCH 6/6] #1296 Fix submitted. + +--- + src/tiffcomposite.cpp | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/tiffcomposite.cpp b/src/tiffcomposite.cpp +index c6b860d..0c9b9c4 100644 +--- a/src/tiffcomposite.cpp ++++ b/src/tiffcomposite.cpp +@@ -1611,6 +1611,8 @@ namespace Exiv2 { + uint32_t TiffImageEntry::doWriteImage(IoWrapper& ioWrapper, + ByteOrder /*byteOrder*/) const + { ++ if ( !pValue() ) throw Error(21); // #1296 ++ + uint32_t len = pValue()->sizeDataArea(); + if (len > 0) { + #ifdef DEBUG +-- +2.9.4 + diff --git a/SOURCES/exiv2-CVE-2017-17723.patch b/SOURCES/exiv2-CVE-2017-17723.patch new file mode 100644 index 0000000..f20af24 --- /dev/null +++ b/SOURCES/exiv2-CVE-2017-17723.patch @@ -0,0 +1,59 @@ +diff --git a/include/exiv2/value.hpp b/include/exiv2/value.hpp +index 64a8ca7..4e9f285 100644 +--- a/include/exiv2/value.hpp ++++ b/include/exiv2/value.hpp +@@ -1658,11 +1658,13 @@ namespace Exiv2 { + ok_ = true; + return static_cast(value_[n]); + } ++// #55 crash when value_[n].first == LONG_MIN ++#define LARGE_INT 1000000 + // Specialization for rational + template<> + inline long ValueType::toLong(long n) const + { +- ok_ = (value_[n].second != 0); ++ ok_ = (value_[n].second != 0 && -LARGE_INT < value_[n].first && value_[n].first < LARGE_INT); + if (!ok_) return 0; + return value_[n].first / value_[n].second; + } +@@ -1670,7 +1672,7 @@ namespace Exiv2 { + template<> + inline long ValueType::toLong(long n) const + { +- ok_ = (value_[n].second != 0); ++ ok_ = (value_[n].second != 0 && value_[n].first < LARGE_INT); + if (!ok_) return 0; + return value_[n].first / value_[n].second; + } +diff --git a/src/basicio.cpp b/src/basicio.cpp +index 1ede931..eac756f 100644 +--- a/src/basicio.cpp ++++ b/src/basicio.cpp +@@ -990,6 +990,7 @@ namespace Exiv2 { + DataBuf FileIo::read(long rcount) + { + assert(p_->fp_ != 0); ++ if ( (size_t) rcount > size() ) throw Error(57); + DataBuf buf(rcount); + long readCount = read(buf.pData_, buf.size_); + buf.size_ = readCount; +diff --git a/src/image.cpp b/src/image.cpp +index 31b9b81..eeb1f37 100644 +--- a/src/image.cpp ++++ b/src/image.cpp +@@ -399,7 +399,13 @@ namespace Exiv2 { + ; + + // if ( offset > io.size() ) offset = 0; // Denial of service? +- DataBuf buf(size*count + pad+20); // allocate a buffer ++ ++ // #55 memory allocation crash test/data/POC8 ++ long long allocate = (long long) size*count + pad+20; ++ if ( allocate > (long long) io.size() ) { ++ throw Error(57); ++ } ++ DataBuf buf(allocate); // allocate a buffer + std::memcpy(buf.pData_,dir.pData_+8,4); // copy dir[8:11] into buffer (short strings) + if ( count*size > 4 ) { // read into buffer + size_t restore = io.tell(); // save diff --git a/SOURCES/exiv2-CVE-2017-17725.patch b/SOURCES/exiv2-CVE-2017-17725.patch new file mode 100644 index 0000000..f461cb7 --- /dev/null +++ b/SOURCES/exiv2-CVE-2017-17725.patch @@ -0,0 +1,420 @@ +diff --git a/src/actions.cpp b/src/actions.cpp +index 35c7965..cb905f6 100644 +--- a/src/actions.cpp ++++ b/src/actions.cpp +@@ -59,6 +59,7 @@ EXIV2_RCSID("@(#) $Id: actions.cpp 4719 2017-03-08 20:42:28Z robinwmills $") + #include + #include + #include ++#include + #include // for stat() + #include // for stat() + #ifdef EXV_HAVE_UNISTD_H +@@ -236,33 +237,43 @@ namespace Action { + } + + int Print::run(const std::string& path) +- try { +- path_ = path; +- int rc = 0; +- Exiv2::PrintStructureOption option = Exiv2::kpsNone ; +- switch (Params::instance().printMode_) { +- case Params::pmSummary: rc = printSummary(); break; +- case Params::pmList: rc = printList(); break; +- case Params::pmComment: rc = printComment(); break; +- case Params::pmPreview: rc = printPreviewList(); break; +- case Params::pmStructure: rc = printStructure(std::cout,Exiv2::kpsBasic) ; break; +- case Params::pmRecursive: rc = printStructure(std::cout,Exiv2::kpsRecursive) ; break; +- +- case Params::pmXMP: +- option = option == Exiv2::kpsNone ? Exiv2::kpsXMP : option; // drop +- case Params::pmIccProfile:{ +- option = option == Exiv2::kpsNone ? Exiv2::kpsIccProfile : option; +- _setmode(_fileno(stdout),O_BINARY); +- rc = printStructure(std::cout,option); +- } break; ++ { ++ try { ++ path_ = path; ++ int rc = 0; ++ Exiv2::PrintStructureOption option = Exiv2::kpsNone ; ++ switch (Params::instance().printMode_) { ++ case Params::pmSummary: rc = printSummary(); break; ++ case Params::pmList: rc = printList(); break; ++ case Params::pmComment: rc = printComment(); break; ++ case Params::pmPreview: rc = printPreviewList(); break; ++ case Params::pmStructure: rc = printStructure(std::cout,Exiv2::kpsBasic) ; break; ++ case Params::pmRecursive: rc = printStructure(std::cout,Exiv2::kpsRecursive) ; break; ++ ++ case Params::pmXMP: ++ if (option == Exiv2::kpsNone) ++ option = Exiv2::kpsXMP; ++ // drop ++ case Params::pmIccProfile: ++ if (option == Exiv2::kpsNone) ++ option = Exiv2::kpsIccProfile; ++ _setmode(_fileno(stdout),O_BINARY); ++ rc = printStructure(std::cout,option); ++ break; ++ } ++ return rc; ++ } ++ catch(const Exiv2::AnyError& e) { ++ std::cerr << "Exiv2 exception in print action for file " ++ << path << ":\n" << e << "\n"; ++ return 1; ++ } ++ catch(const std::overflow_error& e) { ++ std::cerr << "std::overflow_error exception in print action for file " ++ << path << ":\n" << e.what() << "\n"; ++ return 1; + } +- return rc; + } +- catch(const Exiv2::AnyError& e) { +- std::cerr << "Exiv2 exception in print action for file " +- << path << ":\n" << e << "\n"; +- return 1; +- } // Print::run + + int Print::printStructure(std::ostream& out, Exiv2::PrintStructureOption option) + { +diff --git a/src/jp2image.cpp b/src/jp2image.cpp +index ac31257..4c072d7 100644 +--- a/src/jp2image.cpp ++++ b/src/jp2image.cpp +@@ -41,6 +41,7 @@ EXIV2_RCSID("@(#) $Id: jp2image.cpp 4759 2017-04-23 10:58:54Z robinwmills $") + #include "error.hpp" + #include "futils.hpp" + #include "types.hpp" ++#include "safe_op.hpp" + + // + standard includes + #include +@@ -269,8 +270,9 @@ namespace Exiv2 + std::cout << "Exiv2::Jp2Image::readMetadata: " + << "Color data found" << std::endl; + #endif ++ + long pad = 3 ; // 3 padding bytes 2 0 0 +- DataBuf data(subBox.length+8); ++ DataBuf data(Safe::add(subBox.length, static_cast(8))); + io_->read(data.pData_,data.size_); + long iccLength = getULong(data.pData_+pad, bigEndian); + DataBuf icc(iccLength); +diff --git a/src/safe_op.hpp b/src/safe_op.hpp +new file mode 100644 +index 0000000..014b7f3 +--- /dev/null ++++ b/src/safe_op.hpp +@@ -0,0 +1,310 @@ ++// ********************************************************* -*- C++ -*- ++/* ++ * Copyright (C) 2004-2017 Exiv2 maintainers ++ * ++ * This program is part of the Exiv2 distribution. ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2 ++ * of the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA. ++ */ ++/*! ++ @file safe_op.hpp ++ @brief Overflow checks for integers ++ @author Dan Čermák (D4N) ++ dan.cermak@cgc-instruments.com ++ @date 14-Dec-17, D4N: created ++ */ ++ ++#ifndef SAFE_OP_HPP_ ++#define SAFE_OP_HPP_ ++ ++#include ++#include ++ ++#ifdef _MSC_VER ++#include ++#endif ++ ++/*! ++ * @brief Arithmetic operations with overflow checks ++ */ ++namespace Safe ++{ ++ /*! ++ * @brief Helper structs for providing integer overflow checks. ++ * ++ * This namespace contains the internal helper structs fallback_add_overflow ++ * and builtin_add_overflow. Both have a public static member function add ++ * with the following interface: ++ * ++ * bool add(T summand_1, T summand_2, T& result) ++ * ++ * where T is the type over which the struct is templated. ++ * ++ * The function performs a check whether the addition summand_1 + summand_2 ++ * can be performed without an overflow. If the operation would overflow, ++ * true is returned and the addition is not performed if it would result in ++ * undefined behavior. If no overflow occurs, the sum is saved in result and ++ * false is returned. ++ * ++ * fallback_add_overflow implements a portable but slower overflow check. ++ * builtin_add_overflow uses compiler builtins (when available) and should ++ * be considerably faster. As builtins are not available for all types, ++ * builtin_add_overflow falls back to fallback_add_overflow when no builtin ++ * is available. ++ */ ++ namespace Internal ++ { ++ /*! ++ * @brief Helper struct to determine whether a type is signed or unsigned ++ ++ * This struct is a backport of std::is_signed from C++11. It has a public ++ * enum with the property VALUE which is true when the type is signed or ++ * false if it is unsigned. ++ */ ++ template ++ struct is_signed ++ { ++ enum ++ { ++ VALUE = T(-1) < T(0) ++ }; ++ }; ++ ++ /*! ++ * @brief Helper struct for SFINAE, from C++11 ++ ++ * This struct has a public typedef called type typedef'd to T if B is ++ * true. Otherwise there is no typedef. ++ */ ++ template ++ struct enable_if ++ { ++ }; ++ ++ /*! ++ * @brief Specialization of enable_if for the case B == true ++ */ ++ template ++ struct enable_if ++ { ++ typedef T type; ++ }; ++ ++ /*! ++ * @brief Fallback overflow checker, specialized via SFINAE ++ * ++ * This struct implements a 'fallback' addition with an overflow check, ++ * i.e. it does not rely on compiler intrinsics. It is specialized via ++ * SFINAE for signed and unsigned integer types and provides a public ++ * static member function add. ++ */ ++ template ++ struct fallback_add_overflow; ++ ++ /*! ++ * @brief Overload of fallback_add_overflow for signed integers ++ */ ++ template ++ struct fallback_add_overflow::VALUE>::type> ++ { ++ /*! ++ * @brief Adds the two summands only if no overflow occurs ++ * ++ * This function performs a check if summand_1 + summand_2 would ++ * overflow and returns true in that case. If no overflow occurs, ++ * the sum is saved in result and false is returned. ++ * ++ * @return true on overflow, false on no overflow ++ * ++ * The check for an overflow is performed before the addition to ++ * ensure that no undefined behavior occurs. The value in result is ++ * only valid when the function returns false. ++ * ++ * Further information: ++ * https://wiki.sei.cmu.edu/confluence/display/c/INT32-C.+Ensure+that+operations+on+signed+integers+do+not+result+in+overflow ++ */ ++ static bool add(T summand_1, T summand_2, T& result) ++ { ++ if (((summand_2 >= 0) && (summand_1 > std::numeric_limits::max() - summand_2)) || ++ ((summand_2 < 0) && (summand_1 < std::numeric_limits::min() - summand_2))) { ++ return true; ++ } else { ++ result = summand_1 + summand_2; ++ return false; ++ } ++ } ++ }; ++ ++ /*! ++ * @brief Overload of fallback_add_overflow for unsigned integers ++ */ ++ template ++ struct fallback_add_overflow::VALUE>::type> ++ { ++ /*! ++ * @brief Adds the two summands only if no overflow occurs ++ * ++ * This function performs a check if summand_1 + summand_2 would ++ * overflow and returns true in that case. If no overflow occurs, ++ * the sum is saved in result and false is returned. ++ * ++ * @return true on overflow, false on no overflow ++ * ++ * Further information: ++ * https://wiki.sei.cmu.edu/confluence/display/c/INT30-C.+Ensure+that+unsigned+integer+operations+do+not+wrap ++ */ ++ static bool add(T summand_1, T summand_2, T& result) ++ { ++ if (summand_1 > std::numeric_limits::max() - summand_2) { ++ return true; ++ } else { ++ result = summand_1 + summand_2; ++ return false; ++ } ++ } ++ }; ++ ++ /*! ++ * @brief Overflow checker using compiler intrinsics ++ * ++ * This struct provides an add function with the same interface & ++ * behavior as fallback_add_overload::add but it relies on compiler ++ * intrinsics instead. This version should be considerably faster than ++ * the fallback version as it can fully utilize available CPU ++ * instructions & the compiler's diagnostic. ++ * ++ * However, as some compilers don't provide intrinsics for certain ++ * types, the default implementation of add is the version from falback. ++ * ++ * The struct is explicitly specialized for each type via #ifdefs for ++ * each compiler. ++ */ ++ template ++ struct builtin_add_overflow ++ { ++ /*! ++ * @brief Add summand_1 and summand_2 and check for overflows. ++ * ++ * This is the default add() function that uses ++ * fallback_add_overflow::add(). All specializations must have ++ * exactly the same interface and behave the same way. ++ */ ++ static inline bool add(T summand_1, T summand_2, T& result) ++ { ++ return fallback_add_overflow::add(summand_1, summand_2, result); ++ } ++ }; ++ ++#if defined(__GNUC__) || defined(__clang__) ++#if __GNUC__ >= 5 ++ ++/*! ++ * This macro pastes a specialization of builtin_add_overflow using gcc's & ++ * clang's __builtin_(s/u)add(l)(l)_overlow() ++ * ++ * The add function is implemented by forwarding the parameters to the intrinsic ++ * and returning its value. ++ * ++ * The intrinsics are documented here: ++ * https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html#Integer-Overflow-Builtins ++ */ ++#define SPECIALIZE_builtin_add_overflow(type, builtin_name) \ ++ template <> \ ++ struct builtin_add_overflow \ ++ { \ ++ static inline bool add(type summand_1, type summand_2, type& result) \ ++ { \ ++ return builtin_name(summand_1, summand_2, &result); \ ++ } \ ++ } ++ ++ SPECIALIZE_builtin_add_overflow(int, __builtin_sadd_overflow); ++ SPECIALIZE_builtin_add_overflow(long, __builtin_saddl_overflow); ++ SPECIALIZE_builtin_add_overflow(long long, __builtin_saddll_overflow); ++ ++ SPECIALIZE_builtin_add_overflow(unsigned int, __builtin_uadd_overflow); ++ SPECIALIZE_builtin_add_overflow(unsigned long, __builtin_uaddl_overflow); ++ SPECIALIZE_builtin_add_overflow(unsigned long long, __builtin_uaddll_overflow); ++ ++#undef SPECIALIZE_builtin_add_overflow ++#endif ++ ++#elif defined(_MSC_VER) ++ ++/*! ++ * This macro pastes a specialization of builtin_add_overflow using MSVC's ++ * U(Int/Long/LongLong)Add. ++ * ++ * The add function is implemented by forwarding the parameters to the ++ * intrinsic. As MSVC's intrinsics return S_OK on success, this specialization ++ * returns whether the intrinsics return value does not equal S_OK. This ensures ++ * a uniform interface of the add function (false is returned when no overflow ++ * occurs, true on overflow). ++ * ++ * The intrinsics are documented here: ++ * https://msdn.microsoft.com/en-us/library/windows/desktop/ff516460(v=vs.85).aspx ++ */ ++#define SPECIALIZE_builtin_add_overflow_WIN(type, builtin_name) \ ++ template <> \ ++ struct builtin_add_overflow \ ++ { \ ++ static inline bool add(type summand_1, type summand_2, type& result) \ ++ { \ ++ return builtin_name(summand_1, summand_2, &result) != S_OK; \ ++ } \ ++ } ++ ++ SPECIALIZE_builtin_add_overflow_WIN(unsigned int, UIntAdd); ++ SPECIALIZE_builtin_add_overflow_WIN(unsigned long, ULongAdd); ++ SPECIALIZE_builtin_add_overflow_WIN(unsigned long long, ULongLongAdd); ++ ++#undef SPECIALIZE_builtin_add_overflow_WIN ++ ++#endif ++ ++ } // namespace Internal ++ ++ /*! ++ * @brief Safe addition, throws an exception on overflow. ++ * ++ * This function returns the result of summand_1 and summand_2 only when the ++ * operation would not overflow, otherwise an exception of type ++ * std::overflow_error is thrown. ++ * ++ * @param[in] summand_1, summand_2 summands to be summed up ++ * @return the sum of summand_1 and summand_2 ++ * @throws std::overflow_error if the addition would overflow ++ * ++ * This function utilizes compiler builtins when available and should have a ++ * very small performance hit then. When builtins are unavailable, a more ++ * extensive check is required. ++ * ++ * Builtins are available for the following configurations: ++ * - GCC/Clang for signed and unsigned int, long and long long (not char & short) ++ * - MSVC for unsigned int, long and long long ++ */ ++ template ++ T add(T summand_1, T summand_2) ++ { ++ T res = 0; ++ if (Internal::builtin_add_overflow::add(summand_1, summand_2, res)) { ++ throw std::overflow_error("Overflow in addition"); ++ } ++ return res; ++ } ++ ++} // namespace Safe ++ ++#endif // SAFE_OP_HPP_ diff --git a/SOURCES/exiv2-CVE-2017-5772.patch b/SOURCES/exiv2-CVE-2017-5772.patch new file mode 100644 index 0000000..f553d7d --- /dev/null +++ b/SOURCES/exiv2-CVE-2017-5772.patch @@ -0,0 +1,85 @@ +diff --git a/src/cr2image.cpp b/src/cr2image.cpp +index 516e170..8a752b0 100644 +--- a/src/cr2image.cpp ++++ b/src/cr2image.cpp +@@ -107,8 +107,6 @@ namespace Exiv2 { + throw Error(3, "CR2"); + } + clearMetadata(); +- std::ofstream devnull; +- printStructure(devnull, kpsRecursive, 0); + ByteOrder bo = Cr2Parser::decode(exifData_, + iptcData_, + xmpData_, +diff --git a/src/crwimage.cpp b/src/crwimage.cpp +index 232919c..58240fd 100644 +--- a/src/crwimage.cpp ++++ b/src/crwimage.cpp +@@ -131,15 +131,8 @@ namespace Exiv2 { + throw Error(33); + } + clearMetadata(); +- // read all metadata into memory +- // we should put this into clearMetadata(), however it breaks the test suite! +- try { +- std::ofstream devnull; +- printStructure(devnull,kpsRecursive,0); +- } catch (Exiv2::Error& /* e */) { +- DataBuf file(io().size()); +- io_->read(file.pData_,file.size_); +- } ++ DataBuf file( (long) io().size()); ++ io_->read(file.pData_,file.size_); + + CrwParser::decode(this, io_->mmap(), io_->size()); + +diff --git a/src/orfimage.cpp b/src/orfimage.cpp +index 25651bd..9bd7a02 100644 +--- a/src/orfimage.cpp ++++ b/src/orfimage.cpp +@@ -119,8 +119,6 @@ namespace Exiv2 { + throw Error(3, "ORF"); + } + clearMetadata(); +- std::ofstream devnull; +- printStructure(devnull, kpsRecursive, 0); + ByteOrder bo = OrfParser::decode(exifData_, + iptcData_, + xmpData_, +diff --git a/src/rw2image.cpp b/src/rw2image.cpp +index 07de437..5922602 100644 +--- a/src/rw2image.cpp ++++ b/src/rw2image.cpp +@@ -130,8 +130,6 @@ namespace Exiv2 { + throw Error(3, "RW2"); + } + clearMetadata(); +- std::ofstream devnull; +- printStructure(devnull, kpsRecursive, 0); + ByteOrder bo = Rw2Parser::decode(exifData_, + iptcData_, + xmpData_, +diff --git a/src/tiffimage.cpp b/src/tiffimage.cpp +index de66068..98da12b 100644 +--- a/src/tiffimage.cpp ++++ b/src/tiffimage.cpp +@@ -185,10 +185,6 @@ namespace Exiv2 { + } + clearMetadata(); + +- // recursively print the structure to /dev/null to ensure all metadata is in memory +- // must be recursive to handle NEFs which stores the raw image in a subIFDs +- std::ofstream devnull; +- printStructure(devnull,kpsRecursive,0); + ByteOrder bo = TiffParser::decode(exifData_, + iptcData_, + xmpData_, +@@ -200,7 +196,7 @@ namespace Exiv2 { + Exiv2::ExifKey key("Exif.Image.InterColorProfile"); + Exiv2::ExifData::iterator pos = exifData_.findKey(key); + if ( pos != exifData_.end() ) { +- iccProfile_.alloc(pos->count()); ++ iccProfile_.alloc(pos->count()*pos->typeSize()); + pos->copy(iccProfile_.pData_,bo); + } + diff --git a/SPECS/compat-exiv2-026.spec b/SPECS/compat-exiv2-026.spec new file mode 100644 index 0000000..0a85622 --- /dev/null +++ b/SPECS/compat-exiv2-026.spec @@ -0,0 +1,88 @@ + +Name: compat-exiv2-026 +Version: 0.26 +Release: 1%{?dist} +Summary: Compatibility package with the exiv2 library in version 0.26 + +License: GPLv2+ +URL: http://www.exiv2.org/ +Source0: http://www.exiv2.org/builds/exiv2-%{version}-trunk.tar.gz + +## upstream patches +Patch6: 0006-1296-Fix-submitted.patch + +Patch10: exiv2-CVE-2017-17723.patch +Patch11: exiv2-CVE-2017-17725.patch +Patch12: exiv2-CVE-2017-5772.patch + +BuildRequires: expat-devel +BuildRequires: gettext +BuildRequires: pkgconfig +BuildRequires: pkgconfig(libcurl) +BuildRequires: zlib-devel + +Conflicts: exiv2-libs < 0.27 + +%description +A command line utility to access image metadata, allowing one to: +* print the Exif metadata of Jpeg images as summary info, interpreted values, + or the plain data for each tag +* print the Iptc metadata of Jpeg images +* print the Jpeg comment of Jpeg images +* set, add and delete Exif and Iptc metadata of Jpeg images +* adjust the Exif timestamp (that's how it all started...) +* rename Exif image files according to the Exif timestamp +* extract, insert and delete Exif metadata (including thumbnails), + Iptc metadata and Jpeg comments + + +%prep +%autosetup -n exiv2-trunk -p1 + + +%build +# exiv2: embedded copy of exempi should be compiled with BanAllEntityUsage +# https://bugzilla.redhat.com/show_bug.cgi?id=888769 +export CPPFLAGS="-DBanAllEntityUsage=1" + +%configure \ + --disable-rpath \ + --disable-static + +# rpath +sed -i 's|^hardcode_libdir_flag_spec=.*|hardcode_libdir_flag_spec=""|g' libtool +sed -i 's|^runpath_var=LD_RUN_PATH|runpath_var=DIE_RPATH_DIE|g' libtool + +make %{?_smp_mflags} + +%install +rm -rf %{buildroot} + +make install DESTDIR=%{buildroot} + +## Unpackaged files +rm -rf %{buildroot}%{_bindir}/exiv2 +rm -rf %{buildroot}%{_libdir}/libexiv2.la +rm -rf %{buildroot}%{_datadir}/locale/* +rm -rf %{buildroot}%{_mandir}/* +rm -rf %{buildroot}%{_libdir}/pkgconfig/exiv2.pc +rm -rf %{buildroot}%{_includedir}/exiv2 +rm -rf mv %{buildroot}%{_libdir}/libexiv2.so + +## fix perms on installed lib +ls -l %{buildroot}%{_libdir}/libexiv2.so.* +chmod 755 %{buildroot}%{_libdir}/libexiv2.so.* + +%post -p /sbin/ldconfig +%postun -p /sbin/ldconfig + +%files +%doc COPYING README +%{_libdir}/libexiv2.so.26* + + +%changelog +* Tue Jan 29 2019 Jan Grulich - 0.26-1 +- Spec file based on exiv2 package to provide old libraries before API change + Resolves: bz#1668355 +