diff options
author | Eirik Aavitsland <eirik.aavitsland@qt.io> | 2022-05-13 11:42:35 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2022-05-19 11:07:52 +0000 |
commit | e46b3dc574bdf51e1e5bf01444780b0c25ba0b85 (patch) | |
tree | 9b64dfb37bd74e09fed63293b822ec4630de47d2 | |
parent | 7dbf048f1a97c8a25aa8bf21389787805b3861b8 (diff) |
Add some basic checking against corrupt input
Fixes: QTBUG-103454
Change-Id: I169b0de8465bc5d90aebfd8250db0361819065c5
Reviewed-by: Robert Löhning <robert.loehning@qt.io>
(cherry picked from commit 34731687ee77c59607db9d88c6361111631e48c6)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r-- | src/plugins/imageformats/icns/qicnshandler.cpp | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/src/plugins/imageformats/icns/qicnshandler.cpp b/src/plugins/imageformats/icns/qicnshandler.cpp index 195abee..5089c42 100644 --- a/src/plugins/imageformats/icns/qicnshandler.cpp +++ b/src/plugins/imageformats/icns/qicnshandler.cpp @@ -515,6 +515,9 @@ static bool parseIconEntryInfo(ICNSEntry &icon) } icon.height = icon.width; } + // Sanity check + if (icon.width == 0 || icon.width > 4096 || icon.depth > 32) + return false; return true; } @@ -685,7 +688,7 @@ bool QICNSHandler::canRead() const bool QICNSHandler::read(QImage *outImage) { QImage img; - if (!ensureScanned()) { + if (!ensureScanned() || m_currentIconIndex >= m_icons.size()) { qWarning("QICNSHandler::read(): The device wasn't parsed properly!"); return false; } @@ -892,7 +895,7 @@ bool QICNSHandler::scanDevice() return false; const qint64 blockDataOffset = device()->pos(); - if (!isBlockHeaderValid(blockHeader)) { + if (!isBlockHeaderValid(blockHeader, ICNSBlockHeaderSize + filelength - blockDataOffset)) { qWarning("QICNSHandler::scanDevice(): Failed, bad header at pos %s. OSType \"%s\", length %u", QByteArray::number(blockDataOffset).constData(), nameFromOSType(blockHeader.ostype).constData(), blockHeader.length); @@ -927,11 +930,14 @@ bool QICNSHandler::scanDevice() case ICNSBlockHeader::TypeOdrp: // Icns container seems to have an embedded icon variant container // Let's start a scan for entries - while (device()->pos() < nextBlockOffset) { + while (!stream.atEnd() && device()->pos() < nextBlockOffset) { ICNSBlockHeader icon; stream >> icon; + if (stream.status() != QDataStream::Ok) + return false; // Check for incorrect variant entry header and stop scan - if (!isBlockHeaderValid(icon, blockDataLength)) + quint64 remaining = blockDataLength - (device()->pos() - blockDataOffset); + if (!isBlockHeaderValid(icon, ICNSBlockHeaderSize + remaining)) break; if (!addEntry(icon, device()->pos(), blockHeader.ostype)) return false; @@ -1003,7 +1009,7 @@ bool QICNSHandler::scanDevice() break; } } - return true; + return (m_icons.size() > 0); } const ICNSEntry &QICNSHandler::getIconMask(const ICNSEntry &icon) const |