diff options
-rw-r--r-- | include/core/SkFlattenableBuffers.h | 17 | ||||
-rw-r--r-- | samplecode/SampleFilterFuzz.cpp | 28 | ||||
-rw-r--r-- | src/core/SkColorTable.cpp | 11 | ||||
-rw-r--r-- | src/core/SkImageInfo.cpp | 10 | ||||
-rw-r--r-- | src/core/SkMallocPixelRef.cpp | 9 | ||||
-rw-r--r-- | src/core/SkValidatingReadBuffer.cpp | 4 | ||||
-rw-r--r-- | src/core/SkValidatingReadBuffer.h | 2 | ||||
-rw-r--r-- | src/effects/SkDashPathEffect.cpp | 9 | ||||
-rw-r--r-- | src/effects/SkDisplacementMapEffect.cpp | 2 | ||||
-rwxr-xr-x | src/effects/SkMergeImageFilter.cpp | 3 | ||||
-rw-r--r-- | src/effects/SkTableColorFilter.cpp | 1 | ||||
-rw-r--r-- | src/effects/gradients/SkGradientShader.cpp | 9 | ||||
-rw-r--r-- | src/images/SkImageRef.cpp | 8 |
13 files changed, 90 insertions, 23 deletions
diff --git a/include/core/SkFlattenableBuffers.h b/include/core/SkFlattenableBuffers.h index 00cb77a8d3..aa61f21a7b 100644 --- a/include/core/SkFlattenableBuffers.h +++ b/include/core/SkFlattenableBuffers.h @@ -139,8 +139,13 @@ public: SkData* readByteArrayAsData() { size_t len = this->getArrayCount(); - void* buffer = sk_malloc_throw(len); - (void)this->readByteArray(buffer, len); + void* buffer = NULL; + if (this->validateAvailable(len)) { + buffer = sk_malloc_throw(len); + (void)this->readByteArray(buffer, len); + } else { + len = 0; + } return SkData::NewFromMalloc(buffer, len); } @@ -160,6 +165,14 @@ public: */ virtual bool isValid() const { return true; } + /** This function returns true by default + * If isValidating() is true, it will return whether there's + * at least "size" memory left to read in the stream. + * + * @param size amount of memory that should still be available + */ + virtual bool validateAvailable(size_t size) { return true; } + private: template <typename T> T* readFlattenableT(); uint32_t fFlags; diff --git a/samplecode/SampleFilterFuzz.cpp b/samplecode/SampleFilterFuzz.cpp index 06e14f0e7d..8fa147aca4 100644 --- a/samplecode/SampleFilterFuzz.cpp +++ b/samplecode/SampleFilterFuzz.cpp @@ -111,8 +111,10 @@ static SkDisplacementMapEffect::ChannelSelectorType make_channel_selector_type() } static void make_g_bitmap(SkBitmap& bitmap) { - bitmap.setConfig(SkBitmap::kARGB_8888_Config, kBitmapSize, kBitmapSize); - bitmap.allocPixels(); + bitmap.setConfig((SkBitmap::Config)R(SkBitmap::kConfigCount), kBitmapSize, kBitmapSize); + while (!bitmap.allocPixels()) { + bitmap.setConfig((SkBitmap::Config)R(SkBitmap::kConfigCount), kBitmapSize, kBitmapSize); + } SkBitmapDevice device(bitmap); SkCanvas canvas(&device); canvas.clear(0x00000000); @@ -126,8 +128,10 @@ static void make_g_bitmap(SkBitmap& bitmap) { } static void make_checkerboard_bitmap(SkBitmap& bitmap) { - bitmap.setConfig(SkBitmap::kARGB_8888_Config, kBitmapSize, kBitmapSize); - bitmap.allocPixels(); + bitmap.setConfig((SkBitmap::Config)R(SkBitmap::kConfigCount), kBitmapSize, kBitmapSize); + while (!bitmap.allocPixels()) { + bitmap.setConfig((SkBitmap::Config)R(SkBitmap::kConfigCount), kBitmapSize, kBitmapSize); + } SkBitmapDevice device(bitmap); SkCanvas canvas(&device); canvas.clear(0x00000000); @@ -312,18 +316,24 @@ static void drawClippedBitmap(SkCanvas* canvas, int x, int y, const SkPaint& pai } static void do_fuzz(SkCanvas* canvas) { + SkImageFilter* filter = make_serialized_image_filter(); + #ifdef SK_FUZZER_IS_VERBOSE - static uint32_t filterId = 0; - if (0 == filterId) { + static uint32_t numFilters = 0; + static uint32_t numValidFilters = 0; + if (0 == numFilters) { printf("Fuzzing with %u\n", kSeed); } - printf("Filter no %u\r", filterId); + numFilters++; + if (NULL != filter) { + numValidFilters++; + } + printf("Filter no : %u. Valid filters so far : %u\r", numFilters, numValidFilters); fflush(stdout); - filterId++; #endif SkPaint paint; - SkSafeUnref(paint.setImageFilter(make_serialized_image_filter())); + SkSafeUnref(paint.setImageFilter(filter)); drawClippedBitmap(canvas, 0, 0, paint); } diff --git a/src/core/SkColorTable.cpp b/src/core/SkColorTable.cpp index c719defe86..12ec43ec98 100644 --- a/src/core/SkColorTable.cpp +++ b/src/core/SkColorTable.cpp @@ -90,8 +90,15 @@ SkColorTable::SkColorTable(SkFlattenableReadBuffer& buffer) { fAlphaType = SkToU8(buffer.readUInt()); fCount = buffer.getArrayCount(); - fColors = (SkPMColor*)sk_malloc_throw(fCount * sizeof(SkPMColor)); - SkDEBUGCODE(bool success =) buffer.readColorArray(fColors, fCount); + size_t allocSize = fCount * sizeof(SkPMColor); + SkDEBUGCODE(bool success = false;) + if (buffer.validateAvailable(allocSize)) { + fColors = (SkPMColor*)sk_malloc_throw(allocSize); + SkDEBUGCODE(success =) buffer.readColorArray(fColors, fCount); + } else { + fCount = 0; + fColors = NULL; + } #ifdef SK_DEBUG SkASSERT((unsigned)fCount <= 256); SkASSERT(success); diff --git a/src/core/SkImageInfo.cpp b/src/core/SkImageInfo.cpp index 461bdc0309..967b4f6f08 100644 --- a/src/core/SkImageInfo.cpp +++ b/src/core/SkImageInfo.cpp @@ -8,6 +8,14 @@ #include "SkImageInfo.h" #include "SkFlattenableBuffers.h" +static bool alpha_type_is_valid(SkAlphaType alphaType) { + return (alphaType >= 0) && (alphaType <= kLastEnum_SkAlphaType); +} + +static bool color_type_is_valid(SkColorType colorType) { + return (colorType >= 0) && (colorType <= kLastEnum_SkColorType); +} + void SkImageInfo::unflatten(SkFlattenableReadBuffer& buffer) { fWidth = buffer.read32(); fHeight = buffer.read32(); @@ -16,6 +24,8 @@ void SkImageInfo::unflatten(SkFlattenableReadBuffer& buffer) { SkASSERT(0 == (packed >> 16)); fAlphaType = (SkAlphaType)((packed >> 8) & 0xFF); fColorType = (SkColorType)((packed >> 0) & 0xFF); + buffer.validate(alpha_type_is_valid(fAlphaType) && + color_type_is_valid(fColorType)); } void SkImageInfo::flatten(SkFlattenableWriteBuffer& buffer) const { diff --git a/src/core/SkMallocPixelRef.cpp b/src/core/SkMallocPixelRef.cpp index 9f9ffd8db7..b65197fac8 100644 --- a/src/core/SkMallocPixelRef.cpp +++ b/src/core/SkMallocPixelRef.cpp @@ -143,8 +143,13 @@ SkMallocPixelRef::SkMallocPixelRef(SkFlattenableReadBuffer& buffer) { fRB = buffer.read32(); size_t size = this->info().getSafeSize(fRB); - fStorage = sk_malloc_throw(size); - buffer.readByteArray(fStorage, size); + if (buffer.validateAvailable(size)) { + fStorage = sk_malloc_throw(size); + buffer.readByteArray(fStorage, size); + } else { + fStorage = NULL; + } + if (buffer.readBool()) { fCTable = SkNEW_ARGS(SkColorTable, (buffer)); } else { diff --git a/src/core/SkValidatingReadBuffer.cpp b/src/core/SkValidatingReadBuffer.cpp index 692d0dd4d1..ab6a04a1cf 100644 --- a/src/core/SkValidatingReadBuffer.cpp +++ b/src/core/SkValidatingReadBuffer.cpp @@ -228,6 +228,10 @@ SkTypeface* SkValidatingReadBuffer::readTypeface() { return NULL; } +bool SkValidatingReadBuffer::validateAvailable(size_t size) { + return this->validate((size <= SK_MaxU32) && fReader.isAvailable(static_cast<uint32_t>(size))); +} + SkFlattenable* SkValidatingReadBuffer::readFlattenable(SkFlattenable::Type type) { SkString name; this->readString(&name); diff --git a/src/core/SkValidatingReadBuffer.h b/src/core/SkValidatingReadBuffer.h index febf0c0b42..627c2c42db 100644 --- a/src/core/SkValidatingReadBuffer.h +++ b/src/core/SkValidatingReadBuffer.h @@ -63,6 +63,8 @@ public: virtual bool validate(bool isValid) SK_OVERRIDE; virtual bool isValid() const SK_OVERRIDE; + virtual bool validateAvailable(size_t size) SK_OVERRIDE; + private: bool readArray(void* value, size_t size, size_t elementSize); diff --git a/src/effects/SkDashPathEffect.cpp b/src/effects/SkDashPathEffect.cpp index 10fee23aff..52875bc87d 100644 --- a/src/effects/SkDashPathEffect.cpp +++ b/src/effects/SkDashPathEffect.cpp @@ -554,6 +554,11 @@ SkDashPathEffect::SkDashPathEffect(SkFlattenableReadBuffer& buffer) : INHERITED( fScaleToFit = buffer.readBool(); fCount = buffer.getArrayCount(); - fIntervals = (SkScalar*)sk_malloc_throw(sizeof(SkScalar) * fCount); - buffer.readScalarArray(fIntervals, fCount); + size_t allocSize = sizeof(SkScalar) * fCount; + if (buffer.validateAvailable(allocSize)) { + fIntervals = (SkScalar*)sk_malloc_throw(allocSize); + buffer.readScalarArray(fIntervals, fCount); + } else { + fIntervals = NULL; + } } diff --git a/src/effects/SkDisplacementMapEffect.cpp b/src/effects/SkDisplacementMapEffect.cpp index f43287c4d7..8fc4c86ec5 100644 --- a/src/effects/SkDisplacementMapEffect.cpp +++ b/src/effects/SkDisplacementMapEffect.cpp @@ -188,7 +188,7 @@ bool SkDisplacementMapEffect::onFilterImage(Proxy* proxy, SkImageFilter* displacementInput = getDisplacementInput(); SkASSERT(NULL != displacementInput); if ((colorInput && !colorInput->filterImage(proxy, src, ctm, &color, offset)) || - !displacementInput->filterImage(proxy, src, ctm, &displ, offset)) { + !displacementInput || !displacementInput->filterImage(proxy, src, ctm, &displ, offset)) { return false; } if ((displ.config() != SkBitmap::kARGB_8888_Config) || diff --git a/src/effects/SkMergeImageFilter.cpp b/src/effects/SkMergeImageFilter.cpp index 33673b0639..528fe823eb 100755 --- a/src/effects/SkMergeImageFilter.cpp +++ b/src/effects/SkMergeImageFilter.cpp @@ -165,7 +165,8 @@ SkMergeImageFilter::SkMergeImageFilter(SkFlattenableReadBuffer& buffer) int nbInputs = countInputs(); size_t size = nbInputs * sizeof(fModes[0]); SkASSERT(buffer.getArrayCount() == size); - if (buffer.readByteArray(fModes, size)) { + if (buffer.validate(buffer.getArrayCount() == size) && + buffer.readByteArray(fModes, size)) { for (int i = 0; i < nbInputs; ++i) { buffer.validate(SkIsValidMode((SkXfermode::Mode)fModes[i])); } diff --git a/src/effects/SkTableColorFilter.cpp b/src/effects/SkTableColorFilter.cpp index e15baf6928..203f058364 100644 --- a/src/effects/SkTableColorFilter.cpp +++ b/src/effects/SkTableColorFilter.cpp @@ -189,6 +189,7 @@ SkTable_ColorFilter::SkTable_ColorFilter(SkFlattenableReadBuffer& buffer) : INHE size_t size = buffer.getArrayCount(); SkASSERT(size <= sizeof(storage)); + buffer.validate(size <= sizeof(storage)); buffer.readByteArray(storage, size); SkDEBUGCODE(size_t raw = ) SkPackBits::Unpack8(storage, size, fStorage); diff --git a/src/effects/gradients/SkGradientShader.cpp b/src/effects/gradients/SkGradientShader.cpp index 5d200d18d3..6925ad2e4b 100644 --- a/src/effects/gradients/SkGradientShader.cpp +++ b/src/effects/gradients/SkGradientShader.cpp @@ -154,8 +154,13 @@ SkGradientShaderBase::SkGradientShaderBase(SkFlattenableReadBuffer& buffer) : IN int colorCount = fColorCount = buffer.getArrayCount(); if (colorCount > kColorStorageCount) { - size_t size = sizeof(SkColor) + sizeof(SkPMColor) + sizeof(Rec); - fOrigColors = (SkColor*)sk_malloc_throw(size * colorCount); + size_t allocSize = (sizeof(SkColor) + sizeof(SkPMColor) + sizeof(Rec)) * colorCount; + if (buffer.validateAvailable(allocSize)) { + fOrigColors = reinterpret_cast<SkColor*>(sk_malloc_throw(allocSize)); + } else { + fOrigColors = NULL; + colorCount = fColorCount = 0; + } } else { fOrigColors = fStorage; } diff --git a/src/images/SkImageRef.cpp b/src/images/SkImageRef.cpp index 716519f080..843f4c01f9 100644 --- a/src/images/SkImageRef.cpp +++ b/src/images/SkImageRef.cpp @@ -165,8 +165,12 @@ SkImageRef::SkImageRef(SkFlattenableReadBuffer& buffer, SkBaseMutex* mutex) fDoDither = buffer.readBool(); size_t length = buffer.getArrayCount(); - fStream = SkNEW_ARGS(SkMemoryStream, (length)); - buffer.readByteArray((void*)fStream->getMemoryBase(), length); + if (buffer.validateAvailable(length)) { + fStream = SkNEW_ARGS(SkMemoryStream, (length)); + buffer.readByteArray((void*)fStream->getMemoryBase(), length); + } else { + fStream = NULL; + } fPrev = fNext = NULL; fFactory = NULL; |