diff options
Diffstat (limited to 'src/plugins/imageformats/icns/qicnshandler.cpp')
-rw-r--r-- | src/plugins/imageformats/icns/qicnshandler.cpp | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/src/plugins/imageformats/icns/qicnshandler.cpp b/src/plugins/imageformats/icns/qicnshandler.cpp index dde783c..1bf9074 100644 --- a/src/plugins/imageformats/icns/qicnshandler.cpp +++ b/src/plugins/imageformats/icns/qicnshandler.cpp @@ -462,8 +462,12 @@ static bool parseIconEntryInfo(ICNSEntry &icon) if (isIconCompressed(icon)) return true; // Icon depth: - if (!depth.isEmpty()) - icon.depth = ICNSEntry::Depth(depth.toUInt()); + if (!depth.isEmpty()) { + const uint depthUInt = depth.toUInt(); + if (depthUInt > 32) + return false; + icon.depth = ICNSEntry::Depth(depthUInt); + } // Try mono if depth not found if (icon.depth == ICNSEntry::DepthUnknown) icon.depth = ICNSEntry::DepthMono; @@ -515,6 +519,9 @@ static bool parseIconEntryInfo(ICNSEntry &icon) } icon.height = icon.width; } + // Sanity check + if (icon.width == 0 || icon.width > 4096) + return false; return true; } @@ -685,7 +692,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 +899,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 +934,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 +1013,7 @@ bool QICNSHandler::scanDevice() break; } } - return true; + return (m_icons.size() > 0); } const ICNSEntry &QICNSHandler::getIconMask(const ICNSEntry &icon) const |