diff options
author | Eirik Aavitsland <eirik.aavitsland@qt.io> | 2021-03-01 17:27:21 +0100 |
---|---|---|
committer | Eirik Aavitsland <eirik.aavitsland@qt.io> | 2021-03-05 10:07:32 +0100 |
commit | 3dfd4dd8068284465302ecc46cc024e62a931d1a (patch) | |
tree | 3540aaad504db66e5f25969d6feac7dcafd0aa68 | |
parent | 124d950b34a4b5f3bc7f1fa34336f882dbc3edc5 (diff) | |
download | qtimageformats-3dfd4dd8068284465302ecc46cc024e62a931d1a.tar.gz |
Use checked image allocation on reading
Use the imageIO's common QImage creation function that implements
QImageReader's allocation limit that was introduced in Qt 6.
A few related checks against corrupt image files added as driveby.
Pick-to: 6.1 6.0
Change-Id: If5b87cd1b7b2de67ecd023a82ae2168a032fa52e
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
-rw-r--r-- | src/plugins/imageformats/icns/qicnshandler.cpp | 12 | ||||
-rw-r--r-- | src/plugins/imageformats/jp2/qjp2handler.cpp | 18 | ||||
-rw-r--r-- | src/plugins/imageformats/mng/qmnghandler.cpp | 3 | ||||
-rw-r--r-- | src/plugins/imageformats/tga/qtgafile.cpp | 7 | ||||
-rw-r--r-- | src/plugins/imageformats/tiff/qtiffhandler.cpp | 15 | ||||
-rw-r--r-- | src/plugins/imageformats/wbmp/qwbmphandler.cpp | 4 | ||||
-rw-r--r-- | src/plugins/imageformats/webp/qwebphandler.cpp | 9 |
7 files changed, 39 insertions, 29 deletions
diff --git a/src/plugins/imageformats/icns/qicnshandler.cpp b/src/plugins/imageformats/icns/qicnshandler.cpp index 05b8f5b..b098d13 100644 --- a/src/plugins/imageformats/icns/qicnshandler.cpp +++ b/src/plugins/imageformats/icns/qicnshandler.cpp @@ -534,7 +534,9 @@ static QImage readMask(const ICNSEntry &mask, QDataStream &stream) const qint64 oldPos = stream.device()->pos(); if (!stream.device()->seek(pos)) return QImage(); - QImage img(mask.width, mask.height, QImage::Format_RGB32); + QImage img; + if (!QImageIOHandler::allocateImage(QSize(mask.width, mask.height), QImage::Format_RGB32, &img)) + return QImage(); quint8 byte = 0; quint32 pixel = 0; for (quint32 y = 0; y < mask.height; y++) { @@ -564,7 +566,9 @@ static QImage readLowDepthIcon(const ICNSEntry &icon, QDataStream &stream) const QList<QRgb> colortable = getColorTable(depth); if (colortable.isEmpty()) return QImage(); - QImage img(icon.width, icon.height, format); + QImage img; + if (!QImageIOHandler::allocateImage(QSize(icon.width, icon.height), format, &img)) + return QImage(); img.setColorTable(colortable); quint32 pixel = 0; quint8 byte = 0; @@ -595,7 +599,9 @@ static QImage readLowDepthIcon(const ICNSEntry &icon, QDataStream &stream) static QImage read32bitIcon(const ICNSEntry &icon, QDataStream &stream) { - QImage img = QImage(icon.width, icon.height, QImage::Format_RGB32); + QImage img; + if (!QImageIOHandler::allocateImage(QSize(icon.width, icon.height), QImage::Format_RGB32, &img)) + return QImage(); if (icon.dataFormat != ICNSEntry::RLE24) { for (quint32 y = 0; y < icon.height; y++) { QRgb *line = reinterpret_cast<QRgb *>(img.scanLine(y)); diff --git a/src/plugins/imageformats/jp2/qjp2handler.cpp b/src/plugins/imageformats/jp2/qjp2handler.cpp index 05c7bc1..adc2891 100644 --- a/src/plugins/imageformats/jp2/qjp2handler.cpp +++ b/src/plugins/imageformats/jp2/qjp2handler.cpp @@ -573,17 +573,13 @@ bool Jpeg2000JasperReader::read(QImage *pImage) } // Create a QImage of the correct type - if (jasperColorspaceFamily == JAS_CLRSPC_FAM_RGB) { - qtImage = QImage(qtWidth, qtHeight, hasAlpha - ? QImage::Format_ARGB32 - : QImage::Format_RGB32); - } else if (jasperColorspaceFamily == JAS_CLRSPC_FAM_GRAY) { - if (hasAlpha) { - qtImage = QImage(qtWidth, qtHeight, QImage::Format_ARGB32); - } else { - qtImage = QImage(qtWidth, qtHeight, QImage::Format_Grayscale8); - } - } + QImage::Format qtFormat = QImage::Format_Invalid; + if (jasperColorspaceFamily == JAS_CLRSPC_FAM_RGB) + qtFormat = hasAlpha ? QImage::Format_ARGB32 : QImage::Format_RGB32; + else if (jasperColorspaceFamily == JAS_CLRSPC_FAM_GRAY) + qtFormat = hasAlpha ? QImage::Format_ARGB32 : QImage::Format_Grayscale8; + if (!QImageIOHandler::allocateImage(QSize(qtWidth, qtHeight), qtFormat, &qtImage)) + return false; // Copy data if (oddComponentSubsampling) { diff --git a/src/plugins/imageformats/mng/qmnghandler.cpp b/src/plugins/imageformats/mng/qmnghandler.cpp index b37dca1..a3a731c 100644 --- a/src/plugins/imageformats/mng/qmnghandler.cpp +++ b/src/plugins/imageformats/mng/qmnghandler.cpp @@ -247,7 +247,8 @@ mng_bool QMngHandlerPrivate::processHeader(mng_uint32 iWidth, mng_uint32 iHeight { if (mng_set_canvasstyle(hMNG, iStyle) != MNG_NOERROR) return MNG_FALSE; - image = QImage(iWidth, iHeight, QImage::Format_ARGB32); + if (!QImageIOHandler::allocateImage(QSize(iWidth, iHeight), QImage::Format_ARGB32, &image)) + return MNG_FALSE; image.fill(0); return MNG_TRUE; } diff --git a/src/plugins/imageformats/tga/qtgafile.cpp b/src/plugins/imageformats/tga/qtgafile.cpp index 5d086c6..25caa14 100644 --- a/src/plugins/imageformats/tga/qtgafile.cpp +++ b/src/plugins/imageformats/tga/qtgafile.cpp @@ -42,6 +42,7 @@ #include <QtCore/QIODevice> #include <QtCore/QDebug> #include <QtCore/QDateTime> +#include <QtGui/QImageIOHandler> struct TgaReader { @@ -238,8 +239,8 @@ QImage QTgaFile::readImage() //unsigned char xCorner = desc & 0x10; // 0 = left, 1 = right unsigned char yCorner = desc & 0x20; // 0 = lower, 1 = upper - QImage im(imageWidth, imageHeight, QImage::Format_ARGB32); - if (im.isNull()) + QImage im; + if (!QImageIOHandler::allocateImage(QSize(imageWidth, imageHeight), QImage::Format_ARGB32, &im)) return QImage(); TgaReader *reader = 0; if (bitsPerPixel == 16) @@ -248,6 +249,8 @@ QImage QTgaFile::readImage() reader = new Tga24Reader(); else if (bitsPerPixel == 32) reader = new Tga32Reader(); + else + return QImage(); TgaReader &read = *reader; // For now only deal with yCorner, since no one uses xCorner == 1 diff --git a/src/plugins/imageformats/tiff/qtiffhandler.cpp b/src/plugins/imageformats/tiff/qtiffhandler.cpp index 2f32b6d..417d89f 100644 --- a/src/plugins/imageformats/tiff/qtiffhandler.cpp +++ b/src/plugins/imageformats/tiff/qtiffhandler.cpp @@ -349,13 +349,7 @@ bool QTiffHandler::read(QImage *image) QImage::Format format = d->format; - if (image->size() == d->size && image->format() != format) - image->reinterpretAsFormat(format); - - if (image->size() != d->size || image->format() != format) - *image = QImage(d->size, format); - - if (image->isNull()) { + if (!QImageIOHandler::allocateImage(d->size, format, image)) { d->close(); return false; } @@ -430,9 +424,12 @@ bool QTiffHandler::read(QImage *image) quint32 byteWidth = (format == QImage::Format_Mono) ? (width + 7)/8 : (width * bytesPerPixel); quint32 byteTileWidth = (format == QImage::Format_Mono) ? tileWidth/8 : (tileWidth * bytesPerPixel); tmsize_t byteTileSize = TIFFTileSize(tiff); + if (byteTileSize > image->sizeInBytes() || byteTileSize / tileLength < byteTileWidth) { + d->close(); + return false; + } uchar *buf = (uchar *)_TIFFmalloc(byteTileSize); - if (!buf || byteTileSize / tileLength < byteTileWidth) { - _TIFFfree(buf); + if (!buf) { d->close(); return false; } diff --git a/src/plugins/imageformats/wbmp/qwbmphandler.cpp b/src/plugins/imageformats/wbmp/qwbmphandler.cpp index 5fe8ec9..1f1f711 100644 --- a/src/plugins/imageformats/wbmp/qwbmphandler.cpp +++ b/src/plugins/imageformats/wbmp/qwbmphandler.cpp @@ -197,7 +197,9 @@ QImage WBMPReader::readImage() if (!readWBMPHeader(iodev, &hdr)) return QImage(); - QImage image(hdr.width, hdr.height, QImage::Format_Mono); + QImage image; + if (!QImageIOHandler::allocateImage(QSize(hdr.width, hdr.height), QImage::Format_Mono, &image)) + return QImage(); if (!readWBMPData(iodev, image)) return QImage(); diff --git a/src/plugins/imageformats/webp/qwebphandler.cpp b/src/plugins/imageformats/webp/qwebphandler.cpp index 82d38cb..eb375ec 100644 --- a/src/plugins/imageformats/webp/qwebphandler.cpp +++ b/src/plugins/imageformats/webp/qwebphandler.cpp @@ -122,7 +122,10 @@ bool QWebpHandler::ensureScanned() const that->m_frameCount = WebPDemuxGetI(m_demuxer, WEBP_FF_FRAME_COUNT); that->m_bgColor = QColor::fromRgba(QRgb(WebPDemuxGetI(m_demuxer, WEBP_FF_BACKGROUND_COLOR))); - that->m_composited = new QImage(that->m_features.width, that->m_features.height, QImage::Format_ARGB32); + QSize sz(that->m_features.width, that->m_features.height); + that->m_composited = new QImage; + if (!QImageIOHandler::allocateImage(sz, QImage::Format_ARGB32, that->m_composited)) + return false; if (that->m_features.has_alpha) that->m_composited->fill(Qt::transparent); @@ -195,7 +198,9 @@ bool QWebpHandler::read(QImage *image) return false; QImage::Format format = m_features.has_alpha ? QImage::Format_ARGB32 : QImage::Format_RGB32; - QImage frame(m_iter.width, m_iter.height, format); + QImage frame; + if (!QImageIOHandler::allocateImage(QSize(m_iter.width, m_iter.height), format, &frame)) + return false; uint8_t *output = frame.bits(); size_t output_size = frame.sizeInBytes(); #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN |