Follow up to serialization validation code
1 ) Added check for bool to make sure is it either 0 or 1 and not garbage
2 ) Added more solid kernel size checks in SkMatrixConvolutionImageFilter
3 ) Make sure array size is validated in SkMergeImageFilter
BUG=
R=reed@google.com, mtklein@google.com, senorblanco@google.com, senorblanco@chromium.org
Author: sugoi@chromium.org
Review URL: https://codereview.chromium.org/23548034
git-svn-id: http://skia.googlecode.com/svn/trunk/src@11925 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/core/SkValidatingReadBuffer.cpp b/core/SkValidatingReadBuffer.cpp
index 0ffe650..a0e1a41 100644
--- a/core/SkValidatingReadBuffer.cpp
+++ b/core/SkValidatingReadBuffer.cpp
@@ -44,7 +44,12 @@
// true, which the caller should check to see if an error occurred during the read operation.
bool SkValidatingReadBuffer::readBool() {
- return this->readInt() != 0;
+ uint32_t value = this->readInt();
+ // Boolean value should be either 0 or 1
+ if (value & ~1) {
+ fError = true;
+ }
+ return value != 0;
}
SkColor SkValidatingReadBuffer::readColor() {
diff --git a/effects/SkMatrixConvolutionImageFilter.cpp b/effects/SkMatrixConvolutionImageFilter.cpp
index 909facb..cac30e6 100644
--- a/effects/SkMatrixConvolutionImageFilter.cpp
+++ b/effects/SkMatrixConvolutionImageFilter.cpp
@@ -61,17 +61,27 @@
: INHERITED(buffer) {
fKernelSize.fWidth = buffer.readInt();
fKernelSize.fHeight = buffer.readInt();
- uint32_t size = fKernelSize.fWidth * fKernelSize.fHeight;
- fKernel = SkNEW_ARRAY(SkScalar, size);
- SkDEBUGCODE(uint32_t readSize = )buffer.readScalarArray(fKernel);
- SkASSERT(readSize == size);
+ if ((fKernelSize.fWidth >= 1) && (fKernelSize.fHeight >= 1) &&
+ // Make sure size won't be larger than a signed int,
+ // which would still be extremely large for a kernel,
+ // but we don't impose a hard limit for kernel size
+ (SK_MaxS32 / fKernelSize.fWidth >= fKernelSize.fHeight)) {
+ uint32_t size = fKernelSize.fWidth * fKernelSize.fHeight;
+ fKernel = SkNEW_ARRAY(SkScalar, size);
+ uint32_t readSize = buffer.readScalarArray(fKernel);
+ SkASSERT(readSize == size);
+ buffer.validate(readSize == size);
+ } else {
+ fKernel = 0;
+ }
fGain = buffer.readScalar();
fBias = buffer.readScalar();
fTarget.fX = buffer.readInt();
fTarget.fY = buffer.readInt();
fTileMode = (TileMode) buffer.readInt();
fConvolveAlpha = buffer.readBool();
- buffer.validate(SkScalarIsFinite(fGain) &&
+ buffer.validate((fKernel != 0) &&
+ SkScalarIsFinite(fGain) &&
SkScalarIsFinite(fBias) &&
tile_mode_is_valid(fTileMode));
}
diff --git a/effects/SkMergeImageFilter.cpp b/effects/SkMergeImageFilter.cpp
index a5c32ac..4de1093 100755
--- a/effects/SkMergeImageFilter.cpp
+++ b/effects/SkMergeImageFilter.cpp
@@ -161,7 +161,9 @@
if (hasModes) {
this->initAllocModes();
int nbInputs = countInputs();
- SkASSERT(buffer.getArrayCount() == nbInputs * sizeof(fModes[0]));
+ bool sizeMatches = buffer.getArrayCount() == nbInputs * sizeof(fModes[0]);
+ buffer.validate(sizeMatches);
+ SkASSERT(sizeMatches);
buffer.readByteArray(fModes);
for (int i = 0; i < nbInputs; ++i) {
buffer.validate(SkIsValidMode((SkXfermode::Mode)fModes[i]));