Index: exiv2-0.23/src/enforce.hpp
===================================================================
--- /dev/null
+++ exiv2-0.23/src/enforce.hpp
@@ -0,0 +1,96 @@
+// ********************************************************* -*- C++ -*-
+/*
+ * Copyright (C) 2004-2018 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    enforce.hpp
+  @brief   Port of D's enforce() to C++ & Exiv2
+  @author  Dan Čermák (D4N)
+           <a href="mailto:dan.cermak@cgc-instruments.com">dan.cermak@cgc-instruments.com</a>
+  @date    11-March-18, D4N: created
+ */
+
+#include <string>
+
+#include "error.hpp"
+
+/*!
+ * @brief Ensure that condition is true, otherwise throw an exception of the
+ * type exception_t
+ *
+ * @tparam exception_t  Exception type that is thrown, must provide a
+ * constructor that accepts a single argument to which arg1 is forwarded.
+ *
+ * @todo once we have C++>=11 use variadic templates and std::forward to remove
+ * all overloads of enforce
+ */
+template <typename exception_t, typename T>
+inline void enforce(bool condition, const T& arg1)
+{
+    if (!condition) {
+        throw exception_t(arg1);
+    }
+}
+
+/*!
+ * @brief Ensure that condition is true, otherwise throw an Exiv2::Error with
+ * the given error_code.
+ */
+inline void enforce(bool condition, Exiv2::ErrorCode err_code)
+{
+    if (!condition) {
+        throw Exiv2::Error(err_code);
+    }
+}
+
+/*!
+ * @brief Ensure that condition is true, otherwise throw an Exiv2::Error with
+ * the given error_code & arg1.
+ */
+template <typename T>
+inline void enforce(bool condition, Exiv2::ErrorCode err_code, const T& arg1)
+{
+    if (!condition) {
+        throw Exiv2::Error(err_code, arg1);
+    }
+}
+
+/*!
+ * @brief Ensure that condition is true, otherwise throw an Exiv2::Error with
+ * the given error_code, arg1 & arg2.
+ */
+template <typename T, typename U>
+inline void enforce(bool condition, Exiv2::ErrorCode err_code, const T& arg1, const U& arg2)
+{
+    if (!condition) {
+        throw Exiv2::Error(err_code, arg1, arg2);
+    }
+}
+
+/*!
+ * @brief Ensure that condition is true, otherwise throw an Exiv2::Error with
+ * the given error_code, arg1, arg2 & arg3.
+ */
+template <typename T, typename U, typename V>
+inline void enforce(bool condition, Exiv2::ErrorCode err_code, const T& arg1, const U& arg2, const V& arg3)
+{
+    if (!condition) {
+        throw Exiv2::Error(err_code, arg1, arg2, arg3);
+    }
+}
Index: exiv2-0.23/src/pngchunk.cpp
===================================================================
--- exiv2-0.23.orig/src/pngchunk.cpp
+++ exiv2-0.23/src/pngchunk.cpp
@@ -51,6 +51,7 @@ extern "C" {
 #include "iptc.hpp"
 #include "image.hpp"
 #include "error.hpp"
+#include "enforce.hpp"
 
 // + standard includes
 #include <sstream>
@@ -60,6 +61,7 @@ extern "C" {
 #include <iostream>
 #include <cassert>
 #include <cstdio>
+#include <algorithm>
 
 /*
 
@@ -101,7 +103,7 @@ namespace Exiv2 {
 
 #ifdef DEBUG
         std::cout << "Exiv2::PngChunk::decodeTXTChunk: TXT chunk data: "
-                  << std::string((const char*)arr.pData_, arr.size_) << "\n";
+                  << std::string((const char*)arr.pData_, arr.size_) << std::endl;
 #endif
         parseChunkContent(pImage, key.pData_, key.size_, arr);
 
@@ -168,12 +170,18 @@ namespace Exiv2 {
         }
         else if(type == iTXt_Chunk)
         {
+            const int nullSeparators = std::count(&data.pData_[keysize+3], &data.pData_[data.size_], '\0');
+
+            enforce(nullSeparators >= 2, Exiv2::kerCorruptedMetadata);
+
             // Extract a deflate compressed or uncompressed UTF-8 text chunk
 
             // we get the compression flag after the key
-            const byte* compressionFlag   = data.pData_ + keysize + 1;
+            const byte compressionFlag   = data.pData_[keysize + 1];
             // we get the compression method after the compression flag
-            const byte* compressionMethod = data.pData_ + keysize + 2;
+            const byte compressionMethod = data.pData_[keysize + 2];
+            enforce(compressionFlag == 0x00 || compressionFlag == 0x01, Exiv2::kerCorruptedMetadata);
+            enforce(compressionMethod == 0x00, Exiv2::kerCorruptedMetadata);
             // language description string after the compression technique spec
             std::string languageText((const char*)(data.pData_ + keysize + 3));
             unsigned int languageTextSize = static_cast<unsigned int>(languageText.size());
@@ -181,7 +189,7 @@ namespace Exiv2 {
             std::string translatedKeyText((const char*)(data.pData_ + keysize + 3 + languageTextSize +1));
             unsigned int translatedKeyTextSize = static_cast<unsigned int>(translatedKeyText.size());
 
-            if ( compressionFlag[0] == 0x00 )
+            if ( compressionFlag == 0x00 )
             {
                 // then it's an uncompressed iTXt chunk
 #ifdef DEBUG
@@ -195,7 +203,7 @@ namespace Exiv2 {
                 arr.alloc(textsize);
                 arr = DataBuf(text, textsize);
             }
-            else if ( compressionFlag[0] == 0x01 && compressionMethod[0] == 0x00 )
+            else if ( compressionFlag == 0x01 && compressionMethod == 0x00 )
             {
                 // then it's a zlib compressed iTXt chunk
 #ifdef DEBUG
