mirror of
https://invent.kde.org/frameworks/kimageformats.git
synced 2025-11-22 10:02:43 -05:00
PSD: limit memory usage on corrupted files
This commit is contained in:
@ -384,9 +384,7 @@ static PSDImageResourceSection readImageResourceSection(QDataStream &s, bool *ok
|
||||
*ok = false;
|
||||
break;
|
||||
}
|
||||
// NOTE: Qt device::read() and QDataStream::readRawData() could read less data than specified.
|
||||
// The read code should be improved.
|
||||
irb.data = dev->read(dataSize);
|
||||
irb.data = deviceRead(dev, dataSize);
|
||||
}
|
||||
auto read = irb.data.size();
|
||||
if (read > 0) {
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
|
||||
#include <QImage>
|
||||
#include <QImageIOHandler>
|
||||
#include <QIODevice>
|
||||
|
||||
// Default maximum width and height for the large image plugins.
|
||||
#ifndef KIF_LARGE_IMAGE_PIXEL_LIMIT
|
||||
@ -132,4 +133,48 @@ inline float fppm2dpi(qint32 ppm, bool *ok = nullptr)
|
||||
return ppm2dpi_T<float>(ppm, ok);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief deviceRead
|
||||
* A function for reading from devices.
|
||||
*
|
||||
* Similar to QIODevice::read(qint64) but limits the initial memory allocation. Useful for reading corrupted streams.
|
||||
* \param d The device.
|
||||
* \param maxSize The maximum size to read.
|
||||
* \return The byte array read.
|
||||
*/
|
||||
static QByteArray deviceRead(QIODevice *d, qint64 maxSize)
|
||||
{
|
||||
if (d == nullptr) {
|
||||
return{};
|
||||
}
|
||||
|
||||
const qint64 blockSize = 32 * 1024 * 1024;
|
||||
auto devSize = d->isSequential() ? qint64() : d->size();
|
||||
|
||||
if (devSize > 0) {
|
||||
// random access device
|
||||
maxSize = std::min(maxSize, devSize - d->pos());
|
||||
return d->read(maxSize);
|
||||
} else if (maxSize < blockSize) {
|
||||
// small read
|
||||
return d->read(maxSize);
|
||||
}
|
||||
|
||||
// sequential device
|
||||
QByteArray ba;
|
||||
while (ba.size() < maxSize) {
|
||||
auto toRead = std::min(blockSize, maxSize - ba.size());
|
||||
if (toRead + ba.size() > QByteArray::maxSize()) {
|
||||
break;
|
||||
}
|
||||
auto tmp = d->read(toRead);
|
||||
if (tmp.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
ba.append(tmp);
|
||||
}
|
||||
|
||||
return ba;
|
||||
}
|
||||
|
||||
#endif // UTIL_P_H
|
||||
|
||||
Reference in New Issue
Block a user