diff options
author | Eirik Aavitsland <eirik.aavitsland@qt.io> | 2022-05-13 11:42:35 +0200 |
---|---|---|
committer | Eirik Aavitsland <eirik.aavitsland@qt.io> | 2022-05-16 09:31:06 +0200 |
commit | 34731687ee77c59607db9d88c6361111631e48c6 (patch) | |
tree | e1c7efb841557d414f560ee08a2687136d1ce9b3 | |
parent | 55c3b8d01f69413bd2d28d97e9015d2d69f39ae3 (diff) |
Add some basic checking against corrupt input
Fixes: QTBUG-103454
Pick-to: 6.3 6.2 5.15
Change-Id: I169b0de8465bc5d90aebfd8250db0361819065c5
Reviewed-by: Robert Löhning <robert.loehning@qt.io>
-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 b098d13..f924219 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; } @@ -691,7 +694,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; } @@ -898,7 +901,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); @@ -933,11 +936,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; @@ -1009,7 +1015,7 @@ bool QICNSHandler::scanDevice() break; } } - return true; + return (m_icons.size() > 0); } const ICNSEntry &QICNSHandler::getIconMask(const ICNSEntry &icon) const |