aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/core/SkFlattenableBuffers.h17
-rw-r--r--samplecode/SampleFilterFuzz.cpp28
-rw-r--r--src/core/SkColorTable.cpp11
-rw-r--r--src/core/SkImageInfo.cpp10
-rw-r--r--src/core/SkMallocPixelRef.cpp9
-rw-r--r--src/core/SkValidatingReadBuffer.cpp4
-rw-r--r--src/core/SkValidatingReadBuffer.h2
-rw-r--r--src/effects/SkDashPathEffect.cpp9
-rw-r--r--src/effects/SkDisplacementMapEffect.cpp2
-rwxr-xr-xsrc/effects/SkMergeImageFilter.cpp3
-rw-r--r--src/effects/SkTableColorFilter.cpp1
-rw-r--r--src/effects/gradients/SkGradientShader.cpp9
-rw-r--r--src/images/SkImageRef.cpp8
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;