mirror of
https://invent.kde.org/frameworks/kimageformats.git
synced 2026-02-24 00:12:59 -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;
|
*ok = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// NOTE: Qt device::read() and QDataStream::readRawData() could read less data than specified.
|
irb.data = deviceRead(dev, dataSize);
|
||||||
// The read code should be improved.
|
|
||||||
irb.data = dev->read(dataSize);
|
|
||||||
}
|
}
|
||||||
auto read = irb.data.size();
|
auto read = irb.data.size();
|
||||||
if (read > 0) {
|
if (read > 0) {
|
||||||
|
|||||||
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
#include <QImageIOHandler>
|
#include <QImageIOHandler>
|
||||||
|
#include <QIODevice>
|
||||||
|
|
||||||
// Default maximum width and height for the large image plugins.
|
// Default maximum width and height for the large image plugins.
|
||||||
#ifndef KIF_LARGE_IMAGE_PIXEL_LIMIT
|
#ifndef KIF_LARGE_IMAGE_PIXEL_LIMIT
|
||||||
@ -132,4 +133,48 @@ inline float fppm2dpi(qint32 ppm, bool *ok = nullptr)
|
|||||||
return ppm2dpi_T<float>(ppm, ok);
|
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
|
#endif // UTIL_P_H
|
||||||
|
|||||||
Reference in New Issue
Block a user