media-gfx/exiv2: Add 0.26_p20180319 snapshot
authorAndreas Sturmlechner <asturm@gentoo.org>
Wed, 25 Apr 2018 17:40:31 +0000 (19:40 +0200)
committerAndreas Sturmlechner <asturm@gentoo.org>
Wed, 25 Apr 2018 17:53:27 +0000 (19:53 +0200)
Fixing CVE-2017-17669, CVE-2017-17725, CVE-2017-18005, CVE-2018-4868

Bug: https://bugs.gentoo.org/626214
Bug: https://bugs.gentoo.org/643554
Bug: https://bugs.gentoo.org/647808
Bug: https://bugs.gentoo.org/640978
Package-Manager: Portage-2.3.31, Repoman-2.3.9

media-gfx/exiv2/Manifest
media-gfx/exiv2/exiv2-0.26_p20180319.ebuild [new file with mode: 0644]
media-gfx/exiv2/files/exiv2-0.26_p20180319-CVE-2017-18005.patch [new file with mode: 0644]
media-gfx/exiv2/files/exiv2-0.26_p20180319-CVE-2018-4868.patch [new file with mode: 0644]

index a9b1bd775e2b2097b0ac1113406231abe6664038..ff807541c73b66b9be0d81fd5a97024c5578124a 100644 (file)
@@ -1 +1,2 @@
 DIST exiv2-0.26_p20171104.tar.gz 28368697 BLAKE2B 50013cf0bf30a2a476b02d5db4027fca268a4b38733762eb4c08e5f3bdfaf737038e9a62f7ef471fecb10250d8ae686ef683f9b0ea4ccc5d109440ba534371e4 SHA512 6f6a884d7978e54dceb9ce45248cd0425ff469887c85ef52b0e38cb755970f69fce96b4b5317c8e8070b833f72ca214696042aac71292a6f9c3440f6a369d474
+DIST exiv2-0.26_p20180319.tar.gz 28383543 BLAKE2B 753a2ebdb2033490c0f66cb1fb2574f02125f17813f6cbaf5eca66e053af9a2cdbc1266f0a033f0706ec22b31acd6e87271e426a335a58ee947757b52d283489 SHA512 852ce2cffcc0a2d902a939933127fdf5fa0b50020e1faf3ab0a375b129b9f61c7b97b76d4f39e376e7288d7cc045867bd1a96ae15dd0b7c0bcd1ba15259628e1
diff --git a/media-gfx/exiv2/exiv2-0.26_p20180319.ebuild b/media-gfx/exiv2/exiv2-0.26_p20180319.ebuild
new file mode 100644 (file)
index 0000000..9ba5306
--- /dev/null
@@ -0,0 +1,136 @@
+# Copyright 1999-2018 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=6
+
+PYTHON_COMPAT=( python{2_7,3_4,3_5,3_6} )
+if [[ ${PV} = *9999 ]]; then
+       EGIT_REPO_URI="https://github.com/Exiv2/exiv2.git"
+       EGIT_BRANCH="0.26"
+       GIT_ECLASS=git-r3
+else
+       COMMIT=876b1314ab892cbfa6672b6b94adbeb90db4211f
+       SRC_URI="https://github.com/Exiv2/${PN}/tarball/${COMMIT} -> ${P}.tar.gz"
+       KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~ia64 ~mips ~ppc ~ppc64 ~s390 ~sh ~sparc ~x86 ~amd64-fbsd ~x86-fbsd ~amd64-linux ~x86-linux ~x64-solaris ~x86-solaris"
+fi
+inherit cmake-multilib python-any-r1
+
+DESCRIPTION="EXIF, IPTC and XMP metadata C++ library and command line utility"
+HOMEPAGE="http://www.exiv2.org/"
+
+LICENSE="GPL-2"
+SLOT="0/26"
+IUSE="doc examples nls png webready xmp"
+
+RDEPEND="
+       >=virtual/libiconv-0-r1[${MULTILIB_USEDEP}]
+       nls? ( >=virtual/libintl-0-r1[${MULTILIB_USEDEP}] )
+       png? ( >=sys-libs/zlib-1.2.8-r1[${MULTILIB_USEDEP}] )
+       webready? (
+               net-libs/libssh[${MULTILIB_USEDEP}]
+               net-misc/curl[${MULTILIB_USEDEP}]
+       )
+       xmp? ( >=dev-libs/expat-2.1.0-r3[${MULTILIB_USEDEP}] )
+"
+DEPEND="${RDEPEND}
+       app-text/dos2unix
+       doc? (
+               ${PYTHON_DEPS}
+               app-doc/doxygen
+               dev-libs/libxslt
+               media-gfx/graphviz
+               virtual/pkgconfig
+       )
+       nls? ( sys-devel/gettext )
+"
+
+DOCS=( README doc/ChangeLog doc/cmd.txt )
+
+S="${WORKDIR}/${PN^}-${PN}-${COMMIT:0:7}"
+
+PATCHES=(
+       # master, pending backports for 0.26
+       "${FILESDIR}"/${P}-CVE-2018-4868.patch
+       "${FILESDIR}"/${P}-CVE-2017-18005.patch
+       # TODO: Take to upstream
+       "${FILESDIR}"/${PN}-0.26-fix-docs.patch
+       "${FILESDIR}"/${PN}-0.26-tools-optional.patch
+)
+
+pkg_setup() {
+       use doc && python-any-r1_pkg_setup
+}
+
+src_prepare() {
+       if [[ ${PV} != *9999 ]] ; then
+               if [[ -d po ]] ; then
+                       pushd po > /dev/null || die
+                       local lang
+                       for lang in *.po; do
+                               if [[ -e ${lang} ]] \
+                                               && ! has ${lang/.po/} ${LINGUAS-${lang/.po/}} ; then
+                                       case ${lang} in
+                                               CMakeLists.txt | \
+                                               ${PN}.pot)      ;;
+                                               *) rm -r ${lang} || die ;;
+                                       esac
+                               fi
+                       done
+                       popd > /dev/null || die
+               else
+                       die "Failed to prepare LINGUAS - po directory moved?"
+               fi
+       fi
+
+       # FIXME @upstream:
+       einfo "Converting doc/cmd.txt to UTF-8"
+       iconv -f LATIN1 -t UTF-8 doc/cmd.txt > doc/cmd.txt.tmp || die
+       mv -f doc/cmd.txt.tmp doc/cmd.txt || die
+
+       if use doc; then
+               einfo "Updating doxygen config"
+               doxygen &>/dev/null -u config/Doxyfile || die
+       fi
+
+       dos2unix samples/exiv2json.cpp || die # workaround for CVE-2017-18005 patch
+
+       cmake-utils_src_prepare
+}
+
+multilib_src_configure() {
+       local mycmakeargs=(
+               -DEXIV2_ENABLE_BUILD_SAMPLES=NO
+               -DEXIV2_ENABLE_BUILD_PO=$(usex nls)
+               -DEXIV2_ENABLE_NLS=$(usex nls)
+               -DEXIV2_ENABLE_PNG=$(usex png)
+               -DEXIV2_ENABLE_CURL=$(usex webready)
+               -DEXIV2_ENABLE_SSH=$(usex webready)
+               -DEXIV2_ENABLE_WEBREADY=$(usex webready)
+               -DEXIV2_ENABLE_XMP=$(usex xmp)
+               -DEXIV2_ENABLE_LIBXMP=NO
+               $(multilib_is_native_abi || echo -DEXIV2_ENABLE_TOOLS=NO)
+       )
+
+       cmake-utils_src_configure
+}
+
+multilib_src_compile() {
+       cmake-utils_src_compile
+
+       if multilib_is_native_abi; then
+               use doc && emake -j1 doc
+       fi
+}
+
+multilib_src_install_all() {
+       use xmp && DOCS+=( doc/{COPYING-XMPSDK,README-XMP,cmdxmp.txt} )
+       use doc && HTML_DOCS=( "${S}"/doc/html/. )
+
+       einstalldocs
+       find "${D}" -name '*.la' -delete || die
+
+       if use examples; then
+               docinto examples
+               dodoc samples/*.cpp
+       fi
+}
diff --git a/media-gfx/exiv2/files/exiv2-0.26_p20180319-CVE-2017-18005.patch b/media-gfx/exiv2/files/exiv2-0.26_p20180319-CVE-2017-18005.patch
new file mode 100644 (file)
index 0000000..d74ca59
--- /dev/null
@@ -0,0 +1,484 @@
+From 8e31dd8c14fdc83f387f35dda7b1b70fbdbd70db Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= <piponazo@gmail.com>
+Date: Tue, 19 Dec 2017 19:52:41 +0100
+Subject: [PATCH 3/8] Only print items (Params::prValue) when size > 0
+
+---
+ src/actions.cpp | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/src/actions.cpp b/src/actions.cpp
+index 9f850097..3963cb67 100644
+--- a/src/actions.cpp
++++ b/src/actions.cpp
+@@ -713,8 +713,9 @@ namespace Action {
+                       << std::setfill(' ') << std::right
+                       << md.size();
+         }
+-        if (Params::instance().printItems_ & Params::prValue) {
+-            if (!first) std::cout << "  ";
++        if (Params::instance().printItems_ & Params::prValue && md.size() > 0) {
++            if (!first)
++                std::cout << "  ";
+             first = false;
+             if (   Params::instance().binary_
+                 && (   md.typeId() == Exiv2::undefined
+-- 
+2.17.0
+
+
+From 463485e5c1cc716108880f75b9c573715bf402b1 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= <piponazo@gmail.com>
+Date: Tue, 19 Dec 2017 19:54:17 +0100
+Subject: [PATCH 4/8] Move condition in if statement to discard work earlier
+
+---
+ src/actions.cpp | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/src/actions.cpp b/src/actions.cpp
+index 3963cb67..f51cb488 100644
+--- a/src/actions.cpp
++++ b/src/actions.cpp
+@@ -717,11 +717,10 @@ namespace Action {
+             if (!first)
+                 std::cout << "  ";
+             first = false;
+-            if (   Params::instance().binary_
+-                && (   md.typeId() == Exiv2::undefined
++            if (md.size() > 128 && Params::instance().binary_ && (
++                       md.typeId() == Exiv2::undefined
+                     || md.typeId() == Exiv2::unsignedByte
+-                    || md.typeId() == Exiv2::signedByte)
+-                && md.size() > 128) {
++                    || md.typeId() == Exiv2::signedByte)) {
+                 std::cout << _("(Binary value suppressed)") << std::endl;
+                 return true;
+             }
+-- 
+2.17.0
+
+
+From 7fe7501c01e5d1eec16a736062dd0c34d6408833 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= <piponazo@gmail.com>
+Date: Tue, 19 Dec 2017 19:55:50 +0100
+Subject: [PATCH 5/8] Apply clang-format to Print::printMetadatum
+
+---
+ src/actions.cpp | 110 ++++++++++++++++++++++++------------------------
+ 1 file changed, 55 insertions(+), 55 deletions(-)
+
+diff --git a/src/actions.cpp b/src/actions.cpp
+index f51cb488..b31d6ec6 100644
+--- a/src/actions.cpp
++++ b/src/actions.cpp
+@@ -636,91 +636,90 @@ namespace Action {
+     bool Print::printMetadatum(const Exiv2::Metadatum& md, const Exiv2::Image* pImage)
+     {
+-        if (!grepTag(md.key())) return false;
+-        if (!keyTag (md.key())) return false;
++        if (!grepTag(md.key()))
++            return false;
++        if (!keyTag(md.key()))
++            return false;
+-        if (   Params::instance().unknown_
+-            && md.tagName().substr(0, 2) == "0x") {
++        if (Params::instance().unknown_ && md.tagName().substr(0, 2) == "0x") {
+             return false;
+         }
++
+         bool const manyFiles = Params::instance().files_.size() > 1;
+         if (manyFiles) {
+-            std::cout << std::setfill(' ') << std::left << std::setw(20)
+-                      << path_ << "  ";
++            std::cout << std::setfill(' ') << std::left << std::setw(20) << path_ << "  ";
+         }
++
+         bool first = true;
+         if (Params::instance().printItems_ & Params::prTag) {
+-            if (!first) std::cout << " ";
++            if (!first)
++                std::cout << " ";
+             first = false;
+-            std::cout << "0x" << std::setw(4) << std::setfill('0')
+-                      << std::right << std::hex
+-                      << md.tag();
++            std::cout << "0x" << std::setw(4) << std::setfill('0') << std::right << std::hex << md.tag();
+         }
+         if (Params::instance().printItems_ & Params::prSet) {
+-            if (!first) std::cout << " ";
++            if (!first)
++                std::cout << " ";
+             first = false;
+-            std::cout << "set" ;
++            std::cout << "set";
+         }
+         if (Params::instance().printItems_ & Params::prGroup) {
+-            if (!first) std::cout << " ";
++            if (!first)
++                std::cout << " ";
+             first = false;
+-            std::cout << std::setw(12) << std::setfill(' ') << std::left
+-                      << md.groupName();
++            std::cout << std::setw(12) << std::setfill(' ') << std::left << md.groupName();
+         }
+         if (Params::instance().printItems_ & Params::prKey) {
+-            if (!first) std::cout << " ";
++            if (!first)
++                std::cout << " ";
+             first = false;
+-            std::cout << std::setfill(' ') << std::left << std::setw(44)
+-                      << md.key();
++            std::cout << std::setfill(' ') << std::left << std::setw(44) << md.key();
+         }
+         if (Params::instance().printItems_ & Params::prName) {
+-            if (!first) std::cout << " ";
++            if (!first)
++                std::cout << " ";
+             first = false;
+-            std::cout << std::setw(27) << std::setfill(' ') << std::left
+-                      << md.tagName();
++            std::cout << std::setw(27) << std::setfill(' ') << std::left << md.tagName();
+         }
+         if (Params::instance().printItems_ & Params::prLabel) {
+-            if (!first) std::cout << " ";
++            if (!first)
++                std::cout << " ";
+             first = false;
+-            std::cout << std::setw(30) << std::setfill(' ') << std::left
+-                      << md.tagLabel();
++            std::cout << std::setw(30) << std::setfill(' ') << std::left << md.tagLabel();
+         }
+         if (Params::instance().printItems_ & Params::prType) {
+-            if (!first) std::cout << " ";
++            if (!first)
++                std::cout << " ";
+             first = false;
+             std::cout << std::setw(9) << std::setfill(' ') << std::left;
+             const char* tn = md.typeName();
+             if (tn) {
+                 std::cout << tn;
+-            }
+-            else {
++            } else {
+                 std::ostringstream os;
+                 os << "0x" << std::setw(4) << std::setfill('0') << std::hex << md.typeId();
+                 std::cout << os.str();
+             }
+         }
+         if (Params::instance().printItems_ & Params::prCount) {
+-            if (!first) std::cout << " ";
++            if (!first)
++                std::cout << " ";
+             first = false;
+-            std::cout << std::dec << std::setw(3)
+-                      << std::setfill(' ') << std::right
+-                      << md.count();
++            std::cout << std::dec << std::setw(3) << std::setfill(' ') << std::right << md.count();
+         }
+         if (Params::instance().printItems_ & Params::prSize) {
+-            if (!first) std::cout << " ";
++            if (!first)
++                std::cout << " ";
+             first = false;
+-            std::cout << std::dec << std::setw(3)
+-                      << std::setfill(' ') << std::right
+-                      << md.size();
++            std::cout << std::dec << std::setw(3) << std::setfill(' ') << std::right << md.size();
+         }
+         if (Params::instance().printItems_ & Params::prValue && md.size() > 0) {
+             if (!first)
+                 std::cout << "  ";
+             first = false;
+-            if (md.size() > 128 && Params::instance().binary_ && (
+-                       md.typeId() == Exiv2::undefined
+-                    || md.typeId() == Exiv2::unsignedByte
+-                    || md.typeId() == Exiv2::signedByte)) {
++            if (md.size() > 128 && Params::instance().binary_ &&
++                (md.typeId() == Exiv2::undefined || md.typeId() == Exiv2::unsignedByte ||
++                 md.typeId() == Exiv2::signedByte)) {
+                 std::cout << _("(Binary value suppressed)") << std::endl;
+                 return true;
+             }
+@@ -738,22 +737,22 @@ namespace Action {
+             }
+             if (!done) {
+                 // #1114 - show negative values for SByte
+-                if (md.typeId() != Exiv2::signedByte){
++                if (md.typeId() != Exiv2::signedByte) {
+                     std::cout << std::dec << md.value();
+                 } else {
+                     int value = md.value().toLong();
+-                    std::cout << std::dec << (value<128?value:value-256);
++                    std::cout << std::dec << (value < 128 ? value : value - 256);
+                 }
+             }
+         }
+         if (Params::instance().printItems_ & Params::prTrans) {
+-            if (!first) std::cout << "  ";
++            if (!first)
++                std::cout << "  ";
+             first = false;
+-            if (   Params::instance().binary_
+-                && (   md.typeId() == Exiv2::undefined
+-                    || md.typeId() == Exiv2::unsignedByte
+-                    || md.typeId() == Exiv2::signedByte)
+-                && md.size() > 128) {
++            if (Params::instance().binary_ &&
++                (md.typeId() == Exiv2::undefined || md.typeId() == Exiv2::unsignedByte ||
++                 md.typeId() == Exiv2::signedByte) &&
++                md.size() > 128) {
+                 std::cout << _("(Binary value suppressed)") << std::endl;
+                 return true;
+             }
+@@ -765,16 +764,17 @@ namespace Action {
+                     done = true;
+                 }
+             }
+-            if (!done) std::cout << std::dec << md.print(&pImage->exifData());
++            if (!done)
++                std::cout << std::dec << md.print(&pImage->exifData());
+         }
+         if (Params::instance().printItems_ & Params::prHex) {
+-            if (!first) std::cout << std::endl;
++            if (!first)
++                std::cout << std::endl;
+             first = false;
+-            if (   Params::instance().binary_
+-                && (   md.typeId() == Exiv2::undefined
+-                    || md.typeId() == Exiv2::unsignedByte
+-                    || md.typeId() == Exiv2::signedByte)
+-                && md.size() > 128) {
++            if (Params::instance().binary_ &&
++                (md.typeId() == Exiv2::undefined || md.typeId() == Exiv2::unsignedByte ||
++                 md.typeId() == Exiv2::signedByte) &&
++                md.size() > 128) {
+                 std::cout << _("(Binary value suppressed)") << std::endl;
+                 return true;
+             }
+@@ -784,7 +784,7 @@ namespace Action {
+         }
+         std::cout << std::endl;
+         return true;
+-    } // Print::printMetadatum
++    }  // Print::printMetadatum
+     int Print::printComment()
+     {
+-- 
+2.17.0
+
+
+From 78ddc7a92afaaf58b78d5c49b5c2ad7b60a4e25f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= <piponazo@gmail.com>
+Date: Thu, 21 Dec 2017 16:39:43 +0100
+Subject: [PATCH 6/8] Do not deference value when it does not exist (Thanks
+ D4N)
+
+---
+ samples/exiv2json.cpp | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/samples/exiv2json.cpp b/samples/exiv2json.cpp
+index 505268d9..a81268f0 100644
+--- a/samples/exiv2json.cpp
++++ b/samples/exiv2json.cpp
+@@ -148,6 +148,11 @@ bool isArray(std::string& value)
+ template <class T>
+ void push(Jzon::Node& node,const std::string& key,T i)
+ {
++#define ABORT_IF_I_EMTPY          \
++    if (i->value().size() == 0) { \
++        return;                   \
++    }
++
+     std::string value = i->value().toString();
+     switch ( i->typeId() ) {
+@@ -179,6 +184,7 @@ void push(Jzon::Node& node,const std::string& key,T i)
+         case Exiv2::unsignedRational:
+         case Exiv2::signedRational: {
++             ABORT_IF_I_EMTPY
+              Jzon::Array     arr;
+              Exiv2::Rational rat = i->value().toRational();
+              arr.Add(rat.first );
+@@ -187,6 +193,7 @@ void push(Jzon::Node& node,const std::string& key,T i)
+         } break;
+         case Exiv2::langAlt: {
++             ABORT_IF_I_EMTPY
+              Jzon::Object l ;
+              const Exiv2::LangAltValue& langs = dynamic_cast<const Exiv2::LangAltValue&>(i->value());
+              for ( Exiv2::LangAltValue::ValueType::const_iterator lang = langs.value_.begin()
+-- 
+2.17.0
+
+
+From 871e6e3ced1cdec7e43bf8cb94e269a7f5c09d92 Mon Sep 17 00:00:00 2001
+From: Robin Mills <robin@clanmills.com>
+Date: Thu, 15 Mar 2018 10:43:18 +0000
+Subject: [PATCH 8/8] Fix for getopt(), #199. Use src/getopt_win32 code instead
+ of libc/getopt()
+
+---
+ config/config.mk.in |  2 +-
+ src/CMakeLists.txt  |  6 ++----
+ src/Makefile        | 13 +++++--------
+ src/getopt_win32.c  |  9 +++++++++
+ src/getopt_win32.h  |  7 +++++++
+ src/utils.cpp       |  9 +++------
+ 6 files changed, 27 insertions(+), 19 deletions(-)
+
+diff --git a/config/config.mk.in b/config/config.mk.in
+index 8d920647..4754c722 100644
+--- a/config/config.mk.in
++++ b/config/config.mk.in
+@@ -165,7 +165,7 @@ endif
+ # **********************************************************************
+ # Compilation shortcuts
+ COMPILE.cc = $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c
+-COMPILE.c = $(CC) $(CFLAGS) $(CPPFLAGS) -c
++COMPILE.c  = $(CC) $(CFLAGS) -c
+ # LINK.cc does not need $(LIBS), libtool's dark magic takes care of that
+ # when linking a binary with a libtool library.
+ LINK.cc = $(CXX) $(LDFLAGS)
+diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
+index d4dc6375..dceee236 100644
+--- a/src/CMakeLists.txt
++++ b/src/CMakeLists.txt
+@@ -218,10 +218,8 @@ IF(NOT HAVE_TIMEGM )
+     SET( PATHTEST_SRC     ${PATHTEST_SRC} localtime.c    )
+ ENDIF( NOT HAVE_TIMEGM )
+-IF( MSVC )
+-    SET( EXIV2_SRC        ${EXIV2_SRC}    getopt_win32.c )
+-    SET( LIBEXIV2_SRC     ${LIBEXIV2_SRC} getopt_win32.c )
+-ENDIF( MSVC )
++SET( EXIV2_SRC        ${EXIV2_SRC}    getopt_win32.c )
++SET( LIBEXIV2_SRC     ${LIBEXIV2_SRC} getopt_win32.c )
+ ##
+ # msvn tuning
+diff --git a/src/Makefile b/src/Makefile
+index 8a8366fe..d046e331 100644
+--- a/src/Makefile
++++ b/src/Makefile
+@@ -131,8 +131,7 @@ CCSRC += asfvideo.cpp      \
+        utilsvideo.cpp
+ endif
+-# Add library C source files to this list
+-EXIVCSRC  =
++# C source files
+ ifndef HAVE_TIMEGM
+ CSRC =   localtime.c
+ endif
+@@ -141,9 +140,7 @@ endif
+ EXIV2MAIN = exiv2.cpp
+ EXIV2SRC  = actions.cpp \
+             utils.cpp
+-
+-# C source files for the Exiv2 application
+-EXIVCSRC  =
++EXIVCSRC  = getopt_win32.c
+ # ******************************************************************************
+ # Library
+@@ -176,7 +173,7 @@ OBJ    = $(CCOBJ) $(COBJ)
+ LOBJ   = $(CCLOBJ) $(CLOBJ)
+ EXIV2OBJ  = $(EXIV2MAIN:.cpp=.o) $(EXIV2SRC:.cpp=.o)
+-EXIV2COBJ = $(EXIVCSRC:.c=.o)
++EXIVCOBJ  = $(EXIVCSRC:.c=.o)
+ EXIV2EXE  = $(EXIV2MAIN:.cpp=$(EXEEXT))
+ ifdef DEP_TRACKING
+@@ -251,9 +248,9 @@ lib: $(OBJ)
+ $(BINARY): %: %.o lib
+       @$(LIBTOOL) --mode=link $(LINK.cc) -o $@ $(LIBRARY) $@.o -rpath $(libdir)
+-$(EXIV2EXE): lib $(EXIV2OBJ) $(EXIV2COBJ)
++$(EXIV2EXE): lib $(EXIV2OBJ) $(EXIVCOBJ)
+       mkdir -pv ../bin 2>&1 > /dev/null
+-      @$(LIBTOOL) --mode=link $(LINK.cc) -o ../bin/$@ $(LIBRARY) $(EXIV2OBJ) $(EXIV2COBJ) -rpath $(libdir)
++      @$(LIBTOOL) --mode=link $(LINK.cc) -o ../bin/$@ $(LIBRARY) $(EXIV2OBJ) $(EXIVCOBJ) -rpath $(libdir)
+ install-header:
+       $(INSTALL_DIRS) $(DESTDIR)$(incdir)
+diff --git a/src/getopt_win32.c b/src/getopt_win32.c
+index fca29924..18dfcfbf 100644
+--- a/src/getopt_win32.c
++++ b/src/getopt_win32.c
+@@ -194,6 +194,10 @@ permute_args(panonopt_start, panonopt_end, opt_end, nargv)
+       }
+ }
++#ifdef __GETOPT_DEFINE_ARGV__
++char * const *__argv;
++#endif
++
+ /*
+  * getopt_internal --
+  *    Parse argc/argv argument vector.  Called by user level routines.
+@@ -205,6 +209,11 @@ getopt_internal(nargc, nargv, options)
+       char * const *nargv;
+       const char *options;
+ {
++
++#ifdef __GETOPT_DEFINE_ARGV__
++    __argv=nargv;
++#endif
++
+       char *oli;                              /* option letter list index */
+       int optchar;
+diff --git a/src/getopt_win32.h b/src/getopt_win32.h
+index 6b6f643b..cd5760a3 100644
+--- a/src/getopt_win32.h
++++ b/src/getopt_win32.h
+@@ -38,6 +38,13 @@
+ extern "C" {
+ #endif
++#if !defined(_WIN32) &&  !defined(__CYGWIN__) && !defined(__MINGW__) && !defined(_MSC_VER)
++// the symbol __argv (and __argc and __progname and __env) are defined in Windows environments
++// for *ix environments, __argv is declared here, defined: getopt_win32.c, init'd: getopt_internal()
++#define __GETOPT_DEFINE_ARGV__
++extern char * const *__argv;
++#endif
++
+ extern int   opterr;      /* if error message should be printed */
+ extern int   optind;      /* index into parent argv vector */
+ extern int   optopt;      /* character checked for validity */
+diff --git a/src/utils.cpp b/src/utils.cpp
+index a3d36497..2a092330 100644
+--- a/src/utils.cpp
++++ b/src/utils.cpp
+@@ -32,18 +32,15 @@ EXIV2_RCSID("@(#) $Id$")
+ #include "config.h"
+ #include "utils.hpp"
+-
+-// + standard includes
+-#if defined(_MSC_VER) || defined(__MINGW__)
+-# include "getopt_win32.h"
+-#endif
++#include "getopt_win32.h"
+ #if defined(_MSC_VER)
+ # define S_ISREG(m)      (((m) & S_IFMT) == S_IFREG)
+ #endif
++// + standard includes
+ #ifdef EXV_HAVE_UNISTD_H
+-# include <unistd.h>                     // for getopt(), stat()
++# include <unistd.h>                     // for stat()
+ #endif
+ #include <sys/types.h>
+-- 
+2.17.0
+
diff --git a/media-gfx/exiv2/files/exiv2-0.26_p20180319-CVE-2018-4868.patch b/media-gfx/exiv2/files/exiv2-0.26_p20180319-CVE-2018-4868.patch
new file mode 100644 (file)
index 0000000..a594a2b
--- /dev/null
@@ -0,0 +1,39 @@
+From ce4f575e106697c0e513091e95a7cd12ed6a488b Mon Sep 17 00:00:00 2001\r
+From: =?UTF-8?q?Dan=20=C4=8Cerm=C3=A1k?= <dan.cermak@cgc-instruments.com>\r
+Date: Tue, 9 Jan 2018 21:18:36 +0100\r
+Subject: [PATCH 1/8] Add check for DataBuf.size_ in Jp2Image::readMetadata()\r
+\r
+When parsing a subBox that is a ColorHeader, a length is extracted\r
+from the input file and fed directly into DataBuf() (which calls\r
+malloc). A crafted input file can provide arbitrarily (up to\r
+max(uint32_t)-8) large values and result in excessive memory\r
+allocation.\r
+\r
+This commit adds a check for the new size of DataBuf so that it is not\r
+larger than the remaining size of the file.\r
+\r
+This fixes #202 aka CVE-2018-4868\r
+---\r
+ src/jp2image.cpp | 7 ++++++-\r
+ 1 file changed, 6 insertions(+), 1 deletion(-)\r
+\r
+diff --git a/src/jp2image.cpp b/src/jp2image.cpp\r
+index a308bfd9..3cebc2a8 100644\r
+--- a/src/jp2image.cpp\r
++++ b/src/jp2image.cpp\r
+@@ -272,7 +272,12 @@ namespace Exiv2\r
+ #endif\r
\r
+                             const long pad = 3 ; // 3 padding bytes 2 0 0\r
+-                            DataBuf data(Safe::add(subBox.length, static_cast<uint32_t>(8)));\r
++                          const size_t data_length = Safe::add(subBox.length, static_cast<uint32_t>(8));\r
++                          // data_length makes no sense if it is larger than the rest of the file\r
++                          if (data_length > io_->size() - io_->tell()) {\r
++                              throw Error(58);\r
++                          }\r
++                            DataBuf data(data_length);\r
+                             io_->read(data.pData_,data.size_);\r
+                             const long    iccLength = getULong(data.pData_+pad, bigEndian);\r
+                             // subtracting pad from data.size_ is safe:\r
+-- \r
+2.17.0\r