psd: Don't abort on broken images

oss-fuzz/46418
This commit is contained in:
Albert Astals Cid
2022-04-06 00:35:02 +02:00
parent 84d56d00cf
commit 5c47a97b79
3 changed files with 22 additions and 4 deletions

View File

@ -28,6 +28,8 @@
#include "psd_p.h" #include "psd_p.h"
#include "util_p.h"
#include <QDataStream> #include <QDataStream>
#include <QDebug> #include <QDebug>
#include <QImage> #include <QImage>
@ -636,6 +638,12 @@ static bool LoadPSD(QDataStream &stream, const PSDHeader &header, QImage &img)
auto imgChannels = imageChannels(img.format()); auto imgChannels = imageChannels(img.format());
auto channel_num = std::min(qint32(header.channel_count), imgChannels); auto channel_num = std::min(qint32(header.channel_count), imgChannels);
auto raw_count = qsizetype(header.width * header.depth + 7) / 8; auto raw_count = qsizetype(header.width * header.depth + 7) / 8;
if (header.height > kMaxQVectorSize / header.channel_count / sizeof(quint32)) {
qWarning() << "LoadPSD() header height/channel_count too big" << header.height << header.channel_count;
return false;
}
QVector<quint32> strides(header.height * header.channel_count, raw_count); QVector<quint32> strides(header.height * header.channel_count, raw_count);
// Read the compressed stride sizes // Read the compressed stride sizes
if (compression) if (compression)

View File

@ -9,6 +9,8 @@
#include "ras_p.h" #include "ras_p.h"
#include "util_p.h"
#include <QDataStream> #include <QDataStream>
#include <QDebug> #include <QDebug>
#include <QImage> #include <QImage>
@ -102,8 +104,7 @@ static bool LoadRAS(QDataStream &s, const RasHeader &ras, QImage &img)
{ {
s.device()->seek(RasHeader::SIZE); s.device()->seek(RasHeader::SIZE);
// QVector uses some extra space for stuff, hence the 32 here suggested by thiago if (ras.ColorMapLength > kMaxQVectorSize) {
if (ras.ColorMapLength > std::numeric_limits<int>::max() - 32) {
qWarning() << "LoadRAS() unsupported image color map length in file header" << ras.ColorMapLength; qWarning() << "LoadRAS() unsupported image color map length in file header" << ras.ColorMapLength;
return false; return false;
} }
@ -127,8 +128,7 @@ static bool LoadRAS(QDataStream &s, const RasHeader &ras, QImage &img)
qWarning() << "LoadRAS() mistmatch between height and width" << ras.Width << ras.Height << ras.Length << ras.Depth; qWarning() << "LoadRAS() mistmatch between height and width" << ras.Width << ras.Height << ras.Length << ras.Depth;
return false; return false;
} }
// QVector uses some extra space for stuff, hence the 32 here suggested by thiago if (ras.Length > kMaxQVectorSize) {
if (ras.Length > std::numeric_limits<int>::max() - 32) {
qWarning() << "LoadRAS() unsupported image length in file header" << ras.Length; qWarning() << "LoadRAS() unsupported image length in file header" << ras.Length;
return false; return false;
} }

10
src/imageformats/util_p.h Normal file
View File

@ -0,0 +1,10 @@
/*
SPDX-FileCopyrightText: 2022 Albert Astals Cid <aacid@kde.org>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include <limits>
// QVector uses some extra space for stuff, hence the 32 here suggested by Thiago Macieira
static constexpr int kMaxQVectorSize = std::numeric_limits<int>::max() - 32;