#include "SkColorPriv.h"
#include "SkImageDecoder.h"
#include "SkStream.h"
-#include "SkStreamHelpers.h"
+#include "SkStreamPriv.h"
#include "SkTypes.h"
class SkICOImageDecoder : public SkImageDecoder {
bool SkICOImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode)
{
SkAutoMalloc autoMal;
- const size_t length = CopyStreamToStorage(&autoMal, stream);
+ const size_t length = SkCopyStreamToStorage(&autoMal, stream);
if (0 == length) {
return false;
}
//int reservedToo = readByte(buf, 9 + choice*16); //0
//int planes = read2Bytes(buf, 10 + choice*16); //1 - but often 0
//int fakeBitCount = read2Bytes(buf, 12 + choice*16); //should be real - usually 0
- int size = read4Bytes(buf, 14 + choice*16); //matters?
- int offset = read4Bytes(buf, 18 + choice*16);
- if ((size_t)(offset + size) > length)
+ const size_t size = read4Bytes(buf, 14 + choice*16); //matters?
+ const size_t offset = read4Bytes(buf, 18 + choice*16);
+ // promote the sum to 64-bits to avoid overflow
+ if (((uint64_t)offset + size) > length) {
return false;
+ }
// Check to see if this is a PNG image inside the ICO
{
SkMemoryStream subStream(buf + offset, size, false);
SkAutoTDelete<SkImageDecoder> otherDecoder(SkImageDecoder::Factory(&subStream));
if (otherDecoder.get() != NULL) {
+ // Disallow nesting ICO files within one another
+ if (otherDecoder->getFormat() == SkImageDecoder::kICO_Format) {
+ return false;
+ }
// Set fields on the other decoder to be the same as this one.
this->copyFieldsToOther(otherDecoder.get());
if(otherDecoder->decode(&subStream, bm, this->getDefaultPref(), mode)) {