From b43e31b9f31ec482ddea2066fda7ca9315512815 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Fri, 13 May 2022 11:42:35 +0200 Subject: [PATCH] Add some basic checking against corrupt input MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: QTBUG-103454 Pick-to: 6.3 6.2 5.15 Change-Id: I169b0de8465bc5d90aebfd8250db0361819065c5 Reviewed-by: Robert Löhning (cherry picked from commit 34731687ee77c59607db9d88c6361111631e48c6) --- src/plugins/imageformats/icns/qicnshandler.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/plugins/imageformats/icns/qicnshandler.cpp b/src/plugins/imageformats/icns/qicnshandler.cpp index dde783c..d6fc589 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 -- 2.36.0