Index: third_party/WebKit/Source/platform/image-decoders/ico/ICOImageDecoder.cpp |
diff --git a/third_party/WebKit/Source/platform/image-decoders/ico/ICOImageDecoder.cpp b/third_party/WebKit/Source/platform/image-decoders/ico/ICOImageDecoder.cpp |
index a189f8104505aafd491d1a17707f087b3fb92063..a4db195a667e0caf044572c25f8887374e568191 100644 |
--- a/third_party/WebKit/Source/platform/image-decoders/ico/ICOImageDecoder.cpp |
+++ b/third_party/WebKit/Source/platform/image-decoders/ico/ICOImageDecoder.cpp |
@@ -83,6 +83,15 @@ bool ICOImageDecoder::setSize(unsigned width, unsigned height) |
return m_frameSize.isEmpty() ? ImageDecoder::setSize(width, height) : ((IntSize(width, height) == m_frameSize) || setFailed()); |
} |
+bool ICOImageDecoder::frameIsFullyReceivedAtIndex(size_t index) const |
+{ |
+ ASSERT(haveUpdatedFrameCount()); |
+ if (index >= m_dirEntries.size()) |
+ return ImageDecoder::frameIsFullyReceivedAtIndex(index); |
+ const IconDirectoryEntry& dirEntry = m_dirEntries[index]; |
+ return ((dirEntry.m_imageOffset + dirEntry.m_byteSize) <= m_data->size()) || ImageDecoder::frameIsFullyReceivedAtIndex(index); |
+} |
+ |
bool ICOImageDecoder::setFailed() |
{ |
m_bmpReaders.clear(); |
@@ -107,7 +116,6 @@ bool ICOImageDecoder::hotSpotAtIndex(size_t index, IntPoint& hotSpot) const |
return true; |
} |
- |
// static |
bool ICOImageDecoder::compareEntries(const IconDirectoryEntry& a, const IconDirectoryEntry& b) |
{ |
@@ -120,6 +128,12 @@ bool ICOImageDecoder::compareEntries(const IconDirectoryEntry& a, const IconDire |
size_t ICOImageDecoder::decodeFrameCount() |
{ |
decodeSize(); |
+ |
+ for (size_t i = 0; i < m_dirEntries.size(); ++i) { |
+ const IconDirectoryEntry& dirEntry = m_dirEntries[i]; |
+ if ((dirEntry.m_imageOffset + dirEntry.m_byteSize) > m_data->size()) |
aleksandar.stojiljkovic
2016/06/06 14:26:39
frameCount should include only fully received fram
|
+ return i + 1; |
+ } |
return m_dirEntries.size(); |
} |
@@ -147,7 +161,7 @@ void ICOImageDecoder::decode(size_t index, bool onlySize) |
// If we're done decoding this frame, we don't need the BMPImageReader or |
// PNGImageDecoder anymore. (If we failed, these have already been |
// cleared.) |
- } else if ((m_frameBufferCache.size() > index) && (m_frameBufferCache[index].getStatus() == ImageFrame::FrameComplete)) { |
+ } else if (frameIsCompleteAtIndex(index)) { |
m_bmpReaders[index].clear(); |
m_pngDecoders[index].clear(); |
} |
@@ -171,15 +185,15 @@ bool ICOImageDecoder::decodeAtIndex(size_t index) |
if (imageType == Unknown) |
return false; // Not enough data to determine image type yet. |
+ ASSERT(m_frameBufferCache.size() == decodeFrameCount()); |
aleksandar.stojiljkovic
2016/06/06 14:26:39
this assert is copied from previous code but is no
|
if (imageType == BMP) { |
if (!m_bmpReaders[index]) { |
- // We need to have already sized m_frameBufferCache before this, and |
- // we must not resize it again later (see caution in frameCount()). |
- ASSERT(m_frameBufferCache.size() == m_dirEntries.size()); |
m_bmpReaders[index] = adoptPtr(new BMPImageReader(this, dirEntry.m_imageOffset, 0, true)); |
m_bmpReaders[index]->setData(m_data.get()); |
- m_bmpReaders[index]->setBuffer(&m_frameBufferCache[index]); |
} |
+ // Update the pointer to the buffer as it could change after |
+ // m_frameBufferCache.resize(). |
+ m_bmpReaders[index]->setBuffer(&m_frameBufferCache[index]); |
m_frameSize = dirEntry.m_size; |
bool result = m_bmpReaders[index]->decodeBMP(false); |
m_frameSize = IntSize(); |
@@ -273,6 +287,7 @@ ICOImageDecoder::IconDirectoryEntry ICOImageDecoder::readDirectoryEntry() |
entry.m_bitCount = readUint16(6); |
entry.m_hotSpot = IntPoint(); |
} |
+ entry.m_byteSize = readUint32(8); |
entry.m_imageOffset = readUint32(12); |
// Some icons don't have a bit depth, only a color count. Convert the |