Hello community,

here is the log from the commit of package kimageformats for openSUSE:Factory 
checked in at 2019-02-14 14:26:02
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/kimageformats (Old)
 and      /work/SRC/openSUSE:Factory/.kimageformats.new.28833 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "kimageformats"

Thu Feb 14 14:26:02 2019 rev:64 rq:674245 version:5.55.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/kimageformats/kimageformats.changes      
2019-02-04 21:10:44.239883591 +0100
+++ /work/SRC/openSUSE:Factory/.kimageformats.new.28833/kimageformats.changes   
2019-02-14 14:26:11.839851031 +0100
@@ -1,0 +2,12 @@
+Sun Feb 10 22:03:10 UTC 2019 - [email protected]
+
+- Update to 5.55.0
+  * New feature release
+  * For more details please see:
+  * https://www.kde.org/announcements/kde-frameworks-5.55.0.php
+- Changes since 5.54.0:
+  * Too many changes to list here
+- Dropped patches, now upstream:
+  * 0001-Fix-various-OOB-reads-and-writes-in-kimg_tga-and-kim.patch
+
+-------------------------------------------------------------------

Old:
----
  0001-Fix-various-OOB-reads-and-writes-in-kimg_tga-and-kim.patch
  kimageformats-5.54.0.tar.xz

New:
----
  kimageformats-5.55.0.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ kimageformats.spec ++++++
--- /var/tmp/diff_new_pack.K7fFwj/_old  2019-02-14 14:26:13.207850390 +0100
+++ /var/tmp/diff_new_pack.K7fFwj/_new  2019-02-14 14:26:13.211850389 +0100
@@ -16,13 +16,13 @@
 #
 
 
-%define _tar_path 5.54
+%define _tar_path 5.55
 # Full KF5 version (e.g. 5.33.0)
 %{!?_kf5_version: %global _kf5_version %{version}}
 # Last major and minor KF5 version (e.g. 5.33)
 %{!?_kf5_bugfix_version: %define _kf5_bugfix_version %(echo %{_kf5_version} | 
awk -F. '{print $1"."$2}')}
 Name:           kimageformats
-Version:        5.54.0
+Version:        5.55.0
 Release:        0
 Summary:        Image format plugins for Qt
 License:        LGPL-2.1-or-later
@@ -30,8 +30,6 @@
 URL:            https://www.kde.org
 Source:         
http://download.kde.org/stable/frameworks/%{_tar_path}/%{name}-%{version}.tar.xz
 Source1:        baselibs.conf
-# PATCH-FIX-UPSTREAM
-Patch001:       0001-Fix-various-OOB-reads-and-writes-in-kimg_tga-and-kim.patch
 BuildRequires:  cmake >= 3.0
 BuildRequires:  extra-cmake-modules >= %{_kf5_bugfix_version}
 BuildRequires:  fdupes
@@ -65,7 +63,7 @@
 environments.
 
 %prep
-%autosetup -p1
+%setup -q
 
 %build
   %cmake_kf5 -d build

++++++ kimageformats-5.54.0.tar.xz -> kimageformats-5.55.0.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kimageformats-5.54.0/CMakeLists.txt 
new/kimageformats-5.55.0/CMakeLists.txt
--- old/kimageformats-5.54.0/CMakeLists.txt     2019-01-04 22:42:58.000000000 
+0100
+++ new/kimageformats-5.55.0/CMakeLists.txt     2019-02-02 18:22:00.000000000 
+0100
@@ -3,7 +3,7 @@
 project(KImageFormats)
 
 include(FeatureSummary)
-find_package(ECM 5.54.0  NO_MODULE)
+find_package(ECM 5.55.0  NO_MODULE)
 set_package_properties(ECM PROPERTIES TYPE REQUIRED DESCRIPTION "Extra CMake 
Modules." URL 
"https://projects.kde.org/projects/kdesupport/extra-cmake-modules";)
 feature_summary(WHAT REQUIRED_PACKAGES_NOT_FOUND 
FATAL_ON_MISSING_REQUIRED_PACKAGES)
 
@@ -17,7 +17,7 @@
 
 include(CheckIncludeFiles)
 
-set(REQUIRED_QT_VERSION 5.9.0)
+set(REQUIRED_QT_VERSION 5.10.0)
 find_package(Qt5Gui ${REQUIRED_QT_VERSION} REQUIRED NO_MODULE)
 
 find_package(KF5Archive)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kimageformats-5.54.0/autotests/CMakeLists.txt 
new/kimageformats-5.55.0/autotests/CMakeLists.txt
--- old/kimageformats-5.54.0/autotests/CMakeLists.txt   2019-01-04 
22:42:58.000000000 +0100
+++ new/kimageformats-5.55.0/autotests/CMakeLists.txt   2019-02-02 
18:22:00.000000000 +0100
@@ -3,7 +3,7 @@
 include(ECMMarkAsTest)
 include(CMakeParseArguments)
 
-add_definitions(-DPLUGIN_DIR="${CMAKE_CURRENT_BINARY_DIR}/../src")
+add_definitions(-DPLUGIN_DIR="${CMAKE_CURRENT_BINARY_DIR}/../bin")
 remove_definitions(-DQT_NO_CAST_FROM_ASCII)
 
 macro(kimageformats_read_tests)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kimageformats-5.54.0/autotests/readtest.cpp 
new/kimageformats-5.55.0/autotests/readtest.cpp
--- old/kimageformats-5.54.0/autotests/readtest.cpp     2019-01-04 
22:42:58.000000000 +0100
+++ new/kimageformats-5.55.0/autotests/readtest.cpp     2019-02-02 
18:22:00.000000000 +0100
@@ -75,6 +75,7 @@
 int main(int argc, char ** argv)
 {
     QCoreApplication app(argc, argv);
+    QCoreApplication::removeLibraryPath(QStringLiteral(PLUGIN_DIR));
     QCoreApplication::addLibraryPath(QStringLiteral(PLUGIN_DIR));
     QCoreApplication::setApplicationName(QStringLiteral("readtest"));
     QCoreApplication::setApplicationVersion(QStringLiteral("1.0.0"));
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kimageformats-5.54.0/autotests/writetest.cpp 
new/kimageformats-5.55.0/autotests/writetest.cpp
--- old/kimageformats-5.54.0/autotests/writetest.cpp    2019-01-04 
22:42:58.000000000 +0100
+++ new/kimageformats-5.55.0/autotests/writetest.cpp    2019-02-02 
18:22:00.000000000 +0100
@@ -34,6 +34,7 @@
 int main(int argc, char ** argv)
 {
     QCoreApplication app(argc, argv);
+    QCoreApplication::removeLibraryPath(QStringLiteral(PLUGIN_DIR));
     QCoreApplication::addLibraryPath(QStringLiteral(PLUGIN_DIR));
     QCoreApplication::setApplicationName(QStringLiteral("readtest"));
     QCoreApplication::setApplicationVersion(QStringLiteral("1.0.0"));
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kimageformats-5.54.0/src/imageformats/exr.cpp 
new/kimageformats-5.55.0/src/imageformats/exr.cpp
--- old/kimageformats-5.54.0/src/imageformats/exr.cpp   2019-01-04 
22:42:58.000000000 +0100
+++ new/kimageformats-5.55.0/src/imageformats/exr.cpp   2019-02-02 
18:22:00.000000000 +0100
@@ -30,7 +30,7 @@
 
 #include <QImage>
 #include <QDataStream>
-// #include <QDebug>
+#include <QDebug>
 #include <QImageIOPlugin>
 
 class K_IStream: public Imf::IStream
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kimageformats-5.54.0/src/imageformats/gimp_p.h 
new/kimageformats-5.55.0/src/imageformats/gimp_p.h
--- old/kimageformats-5.54.0/src/imageformats/gimp_p.h  2019-01-04 
22:42:58.000000000 +0100
+++ new/kimageformats-5.55.0/src/imageformats/gimp_p.h  2019-02-02 
18:22:00.000000000 +0100
@@ -125,7 +125,8 @@
     PROP_PARASITES = 21,
     PROP_UNIT = 22,
     PROP_PATHS = 23,
-    PROP_USER_UNIT = 24
+    PROP_USER_UNIT = 24,
+    MAX_SUPPORTED_PROPTYPE // should always be at the end so its value is last 
+ 1
 } PropType;
 
 // From GIMP "xcf.c" v1.2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kimageformats-5.54.0/src/imageformats/pcx.cpp 
new/kimageformats-5.55.0/src/imageformats/pcx.cpp
--- old/kimageformats-5.54.0/src/imageformats/pcx.cpp   2019-01-04 
22:42:58.000000000 +0100
+++ new/kimageformats-5.55.0/src/imageformats/pcx.cpp   2019-02-02 
18:22:00.000000000 +0100
@@ -11,7 +11,7 @@
 
 #include <QColor>
 #include <QDataStream>
-// #include <QDebug>
+#include <QDebug>
 #include <QImage>
 
 
@@ -253,6 +253,9 @@
     img = QImage(header.width(), header.height(), QImage::Format_Mono);
     img.setColorCount(2);
 
+    if (img.isNull())
+        return;
+
     for (int y = 0; y < header.height(); ++y) {
         if (s.atEnd()) {
             img = QImage();
@@ -325,6 +328,10 @@
         readLine(s, buf, header);
 
         uchar *p = img.scanLine(y);
+
+        if (!p)
+            return;
+
         unsigned int bpl = qMin(header.BytesPerLine, (quint16)header.width());
         for (unsigned int x = 0; x < bpl; ++x) {
             p[ x ] = buf[ x ];
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kimageformats-5.54.0/src/imageformats/pic.cpp 
new/kimageformats-5.55.0/src/imageformats/pic.cpp
--- old/kimageformats-5.54.0/src/imageformats/pic.cpp   2019-01-04 
22:42:58.000000000 +0100
+++ new/kimageformats-5.55.0/src/imageformats/pic.cpp   2019-02-02 
18:22:00.000000000 +0100
@@ -59,7 +59,10 @@
     header.comment = QByteArray(comment);
 
     header.id.resize(4);
-    s.readRawData(header.id.data(), 4);
+    const int bytesRead = s.readRawData(header.id.data(), 4);
+    if (bytesRead != 4) {
+        header.id.resize(bytesRead);
+    }
 
     s >> header.width;
     s >> header.height;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kimageformats-5.54.0/src/imageformats/psd.cpp 
new/kimageformats-5.55.0/src/imageformats/psd.cpp
--- old/kimageformats-5.54.0/src/imageformats/psd.cpp   2019-01-04 
22:42:58.000000000 +0100
+++ new/kimageformats-5.55.0/src/imageformats/psd.cpp   2019-02-02 
18:22:00.000000000 +0100
@@ -177,6 +177,10 @@
 
     QRgb *image_data = reinterpret_cast<QRgb*>(img.bits());
 
+    if (!image_data) {
+        return false;
+    }
+
     static const channelUpdater updaters[4] = {
         updateRed,
         updateGreen,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kimageformats-5.54.0/src/imageformats/ras.cpp 
new/kimageformats-5.55.0/src/imageformats/ras.cpp
--- old/kimageformats-5.54.0/src/imageformats/ras.cpp   2019-01-04 
22:42:58.000000000 +0100
+++ new/kimageformats-5.55.0/src/imageformats/ras.cpp   2019-02-02 
18:22:00.000000000 +0100
@@ -13,7 +13,7 @@
 
 #include <QImage>
 #include <QDataStream>
-// #include <QDebug>
+#include <QDebug>
 
 namespace   // Private.
 {
@@ -131,6 +131,9 @@
     // Allocate image
     img = QImage(ras.Width, ras.Height, QImage::Format_ARGB32);
 
+    if (img.isNull())
+        return false;
+
     // Reconstruct image from RGB palette if we have a palette
     // TODO: make generic so it works with 24bit or 32bit palettes
     if (ras.ColorMapType == 1 && ras.Depth == 8) {
@@ -248,6 +251,10 @@
     // Read image header.
     RasHeader ras;
     s >> ras;
+
+    if (ras.ColorMapLength > std::numeric_limits<int>::max())
+        return false;
+
     // TODO: add support for old versions of RAS where Length may be zero in 
header
     s.device()->seek(RasHeader::SIZE + ras.Length + ras.ColorMapLength);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kimageformats-5.54.0/src/imageformats/rgb.cpp 
new/kimageformats-5.55.0/src/imageformats/rgb.cpp
--- old/kimageformats-5.54.0/src/imageformats/rgb.cpp   2019-01-04 
22:42:58.000000000 +0100
+++ new/kimageformats-5.55.0/src/imageformats/rgb.cpp   2019-02-02 
18:22:00.000000000 +0100
@@ -27,7 +27,7 @@
 #include <QVector>
 
 #include <QImage>
-// #include <QDebug>
+#include <QDebug>
 
 class RLEData : public QVector<uchar>
 {
@@ -144,13 +144,16 @@
         if (_bpc == 2) {
             _pos++;
         }
+        if (_pos >= _data.end()) {
+            return false;
+        }
         n = *_pos & 0x7f;
         if (!n) {
             break;
         }
 
         if (*_pos++ & 0x80) {
-            for (; i < _xsize && n--; i++) {
+            for (; i < _xsize && _pos < _data.end() && n--; i++) {
                 *dest++ = *_pos;
                 _pos += _bpc;
             }
@@ -309,16 +312,23 @@
         return false;
     }
 
-    _numrows = _ysize * _zsize;
-
     img = QImage(_xsize, _ysize, QImage::Format_RGB32);
 
+    if (_zsize == 0 )
+        return false;
+
     if (_zsize == 2 || _zsize == 4) {
         img = img.convertToFormat(QImage::Format_ARGB32);
     } else if (_zsize > 4) {
 //         qDebug() << "using first 4 of " << _zsize << " channels";
+        // Only let this continue if it won't cause a int overflow later
+        // this is most likely a broken file anyway
+        if (_ysize > std::numeric_limits<int>::max() / _zsize)
+            return false;
     }
 
+    _numrows = _ysize * _zsize;
+
     if (_rle) {
         uint l;
         _starttab = new quint32[_numrows];
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kimageformats-5.54.0/src/imageformats/tga.cpp 
new/kimageformats-5.55.0/src/imageformats/tga.cpp
--- old/kimageformats-5.54.0/src/imageformats/tga.cpp   2019-01-04 
22:42:58.000000000 +0100
+++ new/kimageformats-5.55.0/src/imageformats/tga.cpp   2019-02-02 
18:22:00.000000000 +0100
@@ -24,7 +24,7 @@
 
 #include <QImage>
 #include <QDataStream>
-// #include <QDebug>
+#include <QDebug>
 
 typedef quint32 uint;
 typedef quint16 ushort;
@@ -186,10 +186,14 @@
     // However alpha exists only in the 32 bit format.
     if ((tga.pixel_size == 32) && (tga.flags & 0xf)) {
         img = QImage(tga.width, tga.height, QImage::Format_ARGB32);
+
+        if (numAlphaBits > 8) {
+            return false;
+        }
     }
 
     uint pixel_size = (tga.pixel_size / 8);
-    uint size = tga.width * tga.height * pixel_size;
+    qint64 size = qint64(tga.width) * qint64(tga.height) * pixel_size;
 
     if (size < 1) {
 //          qDebug() << "This TGA file is broken with size " << size;
@@ -200,24 +204,42 @@
     char palette[768];
     if (info.pal) {
         // @todo Support palettes in other formats!
-        s.readRawData(palette, 3 * tga.colormap_length);
+        const int size = 3 * tga.colormap_length;
+        const int dataRead = s.readRawData(palette, size);
+        if (dataRead < size) {
+            memset(&palette[dataRead], 0, size - dataRead);
+        }
     }
 
     // Allocate image.
-    uchar *const image = new uchar[size];
+    uchar *const image = reinterpret_cast<uchar*>(malloc(size));
+    if (!image) {
+        return false;
+    }
+
+    bool valid = true;
 
     if (info.rle) {
         // Decode image.
         char *dst = (char *)image;
-        int num = size;
+        qint64 num = size;
 
         while (num > 0) {
+            if (s.atEnd()) {
+                valid = false;
+                break;
+            }
+
             // Get packet header.
             uchar c;
             s >> c;
 
             uint count = (c & 0x7f) + 1;
             num -= count * pixel_size;
+            if (num < 0) {
+                valid = false;
+                break;
+            }
 
             if (c & 0x80) {
                 // RLE pixels.
@@ -237,7 +259,15 @@
         }
     } else {
         // Read raw image.
-        s.readRawData((char *)image, size);
+        const int dataRead = s.readRawData((char *)image, size);
+        if (dataRead < size) {
+            memset(&image[dataRead], 0, size - dataRead);
+        }
+    }
+
+    if (!valid) {
+        free(image);
+        return false;
     }
 
     // Convert image to internal format.
@@ -294,7 +324,7 @@
     }
 
     // Free image.
-    delete [] image;
+    free(image);
 
     return true;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kimageformats-5.54.0/src/imageformats/xcf.cpp 
new/kimageformats-5.55.0/src/imageformats/xcf.cpp
--- old/kimageformats-5.54.0/src/imageformats/xcf.cpp   2019-01-04 
22:42:58.000000000 +0100
+++ new/kimageformats-5.55.0/src/imageformats/xcf.cpp   2019-02-02 
18:22:00.000000000 +0100
@@ -27,7 +27,9 @@
 #include <QIODevice>
 #include <QStack>
 #include <QVector>
-// #include <QDebug>
+#include <QDebug>
+
+#include <string.h>
 
 #include "gimp_p.h"
 
@@ -86,16 +88,17 @@
         } mask_channel;
 
         bool active;            //!< Is this layer the active layer?
-        quint32 opacity;        //!< The opacity of the layer
-        quint32 visible;        //!< Is the layer visible?
+        quint32 opacity = 255;  //!< The opacity of the layer
+        quint32 visible = 1;    //!< Is the layer visible?
         quint32 linked;     //!< Is this layer linked (geometrically)
         quint32 preserve_transparency; //!< Preserve alpha when drawing on 
layer?
-        quint32 apply_mask;     //!< Apply the layer mask?
+        quint32 apply_mask = 9; //!< Apply the layer mask? Use 9 as 
"uninitilized". Spec says "If the property does not appear for a layer which 
has a layer mask, it defaults to true (1).
+                                //   Robust readers should force this to false 
if the layer has no layer mask.
         quint32 edit_mask;      //!< Is the layer mask the being edited?
         quint32 show_mask;      //!< Show the layer mask rather than the image?
-        qint32 x_offset;        //!< x offset of the layer relative to the 
image
-        qint32 y_offset;        //!< y offset of the layer relative to the 
image
-        quint32 mode;           //!< Combining mode of layer (LayerModeEffects)
+        qint32 x_offset = 0;    //!< x offset of the layer relative to the 
image
+        qint32 y_offset = 0;    //!< y offset of the layer relative to the 
image
+        quint32 mode = 0;       //!< Combining mode of layer (LayerModeEffects)
         quint32 tattoo;     //!< (unique identifier?)
 
         //! As each tile is read from the file, it is buffered here.
@@ -112,6 +115,9 @@
         {
             delete[] name;
         }
+
+        Layer(const Layer &) = delete;
+        Layer &operator=(const Layer &) = delete;
     };
 
     /*!
@@ -126,11 +132,11 @@
         qint32 type;            //!< type of the XCF image (GimpImageBaseType)
 
         quint8 compression;     //!< tile compression method (CompressionType)
-        float x_resolution;     //!< x resolution in dots per inch
-        float y_resolution;     //!< y resolution in dots per inch
+        float x_resolution = -1;//!< x resolution in dots per inch
+        float y_resolution = -1;//!< y resolution in dots per inch
         qint32 tattoo;          //!< (unique identifier?)
         quint32 unit;           //!< Units of The GIMP (inch, mm, pica, etc...)
-        qint32 num_colors;      //!< number of colors in an indexed image
+        qint32 num_colors = 0;  //!< number of colors in an indexed image
         QVector<QRgb> palette;          //!< indexed image color palette
 
         int num_layers;         //!< number of layers
@@ -178,7 +184,7 @@
     static const LayerModes layer_modes[];
 
     bool loadImageProperties(QDataStream &xcf_io, XCFImage &image);
-    bool loadProperty(QDataStream &xcf_io, PropType &type, QByteArray &bytes);
+    bool loadProperty(QDataStream &xcf_io, PropType &type, QByteArray &bytes, 
quint32 &rawType);
     bool loadLayer(QDataStream &xcf_io, XCFImage &xcf_image);
     bool loadLayerProperties(QDataStream &xcf_io, Layer &layer);
     bool composeTiles(XCFImage &xcf_image);
@@ -384,8 +390,9 @@
     while (true) {
         PropType type;
         QByteArray bytes;
+        quint32 rawType;
 
-        if (!loadProperty(xcf_io, type, bytes)) {
+        if (!loadProperty(xcf_io, type, bytes, rawType)) {
 //          qDebug() << "XCF: error loading global image properties";
             return false;
         }
@@ -444,6 +451,7 @@
                 return false;
             }
 
+            xcf_image.palette = QVector<QRgb>();
             xcf_image.palette.reserve(xcf_image.num_colors);
 
             for (int i = 0; i < xcf_image.num_colors; i++) {
@@ -454,7 +462,7 @@
             break;
 
         default:
-//                  qDebug() << "XCF: unimplemented image property" << type
+//                  qDebug() << "XCF: unimplemented image property" << rawType
 //                          << ", size " << bytes.size() << endl;
             break;
         }
@@ -468,11 +476,16 @@
  * \param type returns with the property type.
  * \param bytes returns with the property data.
  * \return true if there were no IO errors.  */
-bool XCFImageFormat::loadProperty(QDataStream &xcf_io, PropType &type, 
QByteArray &bytes)
+bool XCFImageFormat::loadProperty(QDataStream &xcf_io, PropType &type, 
QByteArray &bytes, quint32 &rawType)
 {
-    quint32 foo;
-    xcf_io >> foo;
-    type = PropType(foo); // TODO urks
+    xcf_io >> rawType;
+    if (rawType >= MAX_SUPPORTED_PROPTYPE) {
+        type = MAX_SUPPORTED_PROPTYPE;
+        // return true because we don't really want to totally fail on an 
unsupported property since it may not be fatal
+        return true;
+    }
+
+    type = PropType(rawType);
 
     char *data = nullptr;
     quint32 size;
@@ -486,11 +499,12 @@
         quint32 ncolors;
         xcf_io >> ncolors;
 
+        size = 3 * ncolors + 4;
+
         if (size > 65535 || size < 4) {
             return false;
         }
 
-        size = 3 * ncolors + 4;
         data = new char[size];
 
         // since we already read "ncolors" from the stream, we put that data 
back
@@ -528,7 +542,11 @@
             return false;
         }
         data = new char[size];
-        xcf_io.readRawData(data, size);
+        const quint32 dataRead = xcf_io.readRawData(data, size);
+        if (dataRead < size) {
+//          qDebug() << "XCF: loadProperty read less data than expected" << 
data_length << dataRead;
+            memset(&data[dataRead], 0, size - dataRead);
+        }
     }
 
     if (size != 0 && data) {
@@ -595,11 +613,19 @@
     }
 
     if (layer.mask_offset != 0) {
+        // 9 means its not on the file. Spec says "If the property does not 
appear for a layer which has a layer mask, it defaults to true (1).
+        if (layer.apply_mask == 9) {
+            layer.apply_mask = 1;
+        }
+
         xcf_io.device()->seek(layer.mask_offset);
 
         if (!loadMask(xcf_io, layer)) {
             return false;
         }
+    } else {
+        // Spec says "Robust readers should force this to false if the layer 
has no layer mask."
+        layer.apply_mask = 0;
     }
 
     // Now we should have enough information to initialize the final
@@ -631,8 +657,9 @@
     while (true) {
         PropType type;
         QByteArray bytes;
+        quint32 rawType;
 
-        if (!loadProperty(xcf_io, type, bytes)) {
+        if (!loadProperty(xcf_io, type, bytes, rawType)) {
 //          qDebug() << "XCF: error loading layer properties";
             return false;
         }
@@ -649,6 +676,7 @@
 
         case PROP_OPACITY:
             property >> layer.opacity;
+            layer.opacity = std::min(layer.opacity, 255u);
             break;
 
         case PROP_VISIBLE:
@@ -688,7 +716,7 @@
             break;
 
         default:
-//              qDebug() << "XCF: unimplemented layer property " << type
+//              qDebug() << "XCF: unimplemented layer property " << rawType
 //                      << ", size " << bytes.size() << endl;
             break;
         }
@@ -953,6 +981,46 @@
 
     xcf_io >> width >> height >> bpp >> offset;
 
+    // make sure bpp is correct and complain if it is not
+    switch (layer.type) {
+        case RGB_GIMAGE:
+            if (bpp != 3) {
+                qWarning() << "Found layer of type RGB but with bpp != 3" << 
bpp;
+                bpp = 3;
+            }
+            break;
+        case RGBA_GIMAGE:
+            if (bpp != 4) {
+                qWarning() << "Found layer of type RGBA but with bpp != 4" << 
bpp;
+                bpp = 4;
+            }
+            break;
+        case GRAY_GIMAGE:
+            if (bpp != 1) {
+                qWarning() << "Found layer of type Gray but with bpp != 1" << 
bpp;
+                bpp = 1;
+            }
+            break;
+        case GRAYA_GIMAGE:
+            if (bpp != 2) {
+                qWarning() << "Found layer of type Gray+Alpha but with bpp != 
2" << bpp;
+                bpp = 2;
+            }
+            break;
+        case INDEXED_GIMAGE:
+            if (bpp != 1) {
+                qWarning() << "Found layer of type Indexed but with bpp != 1" 
<< bpp;
+                bpp = 1;
+            }
+            break;
+        case INDEXEDA_GIMAGE:
+            if (bpp != 2) {
+                qWarning() << "Found layer of type Indexed+Alpha but with bpp 
!= 2" << bpp;
+                bpp = 2;
+            }
+            break;
+    }
+
     // GIMP stores images in a "mipmap"-like format (multiple levels of
     // increasingly lower resolution). Only the top level is used here,
     // however.
@@ -1109,7 +1177,11 @@
 
     xcfdata = xcfodata = new uchar[data_length];
 
-    xcf_io.readRawData((char *)xcfdata, data_length);
+    const int dataRead = xcf_io.readRawData((char *)xcfdata, data_length);
+    if (dataRead < data_length) {
+//      qDebug() << "XCF: read less data than expected" << data_length << 
dataRead;
+        memset(&xcfdata[dataRead], 0, data_length - dataRead);
+    }
 
     if (!xcf_io.device()->isOpen()) {
         delete[] xcfodata;
@@ -1215,8 +1287,9 @@
     while (true) {
         PropType type;
         QByteArray bytes;
+        quint32 rawType;
 
-        if (!loadProperty(xcf_io, type, bytes)) {
+        if (!loadProperty(xcf_io, type, bytes, rawType)) {
 //          qDebug() << "XCF: error loading channel properties";
             return false;
         }
@@ -1229,6 +1302,7 @@
 
         case PROP_OPACITY:
             property >> layer.mask_channel.opacity;
+            layer.mask_channel.opacity = std::min(layer.mask_channel.opacity, 
255u);
             break;
 
         case PROP_VISIBLE:
@@ -1249,7 +1323,7 @@
             break;
 
         default:
-//              qDebug() << "XCF: unimplemented channel property " << type
+//              qDebug() << "XCF: unimplemented channel property " << rawType
 //                      << ", size " << bytes.size() << endl;
             break;
         }
@@ -1429,8 +1503,16 @@
         break;
     }
 
-    image.setDotsPerMeterX((int)(xcf_image.x_resolution * INCHESPERMETER));
-    image.setDotsPerMeterY((int)(xcf_image.y_resolution * INCHESPERMETER));
+    if (xcf_image.x_resolution > 0 && xcf_image.y_resolution > 0) {
+        const float dpmx = xcf_image.x_resolution * INCHESPERMETER;
+        if (dpmx > std::numeric_limits<int>::max())
+            return false;
+        const float dpmy = xcf_image.y_resolution * INCHESPERMETER;
+        if (dpmy > std::numeric_limits<int>::max())
+            return false;
+        image.setDotsPerMeterX((int)dpmx);
+        image.setDotsPerMeterY((int)dpmy);
+    }
     return true;
 }
 


Reply via email to