*/
virtual bool validate(bool isValid);
+ /** This function returns true by default
+ * If isValidating() is true, it will return false if the internal error flag is set.
+ * Otherwise, it will return true.
+ */
+ virtual bool isValid() const { return true; }
+
private:
template <typename T> T* readFlattenableT();
uint32_t fFlags;
#include <stdio.h>
#include <time.h>
+//#define SK_ADD_RANDOM_BIT_FLIPS
+//#define SK_FUZZER_IS_VERBOSE
+
static const uint32_t kSeed = (uint32_t)(time(NULL));
static SkRandom gRand(kSeed);
static bool return_large = false;
buffer.validate((width >= 0) && (height >= 0) && (rowBytes >= 0) &&
SkIsValidConfig(config) && validate_alphaType(config, alphaType));
- this->setConfig(config, width, height, rowBytes, alphaType);
- buffer.validate(fRowBytes >= (fWidth * fBytesPerPixel));
+ bool configIsValid = this->setConfig(config, width, height, rowBytes, alphaType);
+ // Note : Using (fRowBytes >= (fWidth * fBytesPerPixel)) in the following test can create false
+ // positives if the multiplication causes an integer overflow. Use the division instead.
+ buffer.validate(configIsValid && (fBytesPerPixel > 0) &&
+ ((fRowBytes / fBytesPerPixel) >= fWidth));
int reftype = buffer.readInt();
if (buffer.validate((SERIALIZE_PIXELTYPE_REF_DATA == reftype) ||
} else {
fInputs[i] = NULL;
}
+ if (!buffer.isValid()) {
+ fInputCount = i; // Do not use fInputs past that point in the destructor
+ break;
+ }
}
SkRect rect;
buffer.readRect(&rect);
- if (buffer.validate(SkIsValidRect(rect))) {
+ if (buffer.isValid() && buffer.validate(SkIsValidRect(rect))) {
uint32_t flags = buffer.readUInt();
fCropRect = CropRect(rect, flags);
}
return !fError;
}
+bool SkValidatingReadBuffer::isValid() const {
+ return !fError;
+}
+
void SkValidatingReadBuffer::setMemory(const void* data, size_t size) {
this->validate(IsPtrAlign4(data) && (SkAlign4(size) == size));
if (!fError) {
virtual SkTypeface* readTypeface() SK_OVERRIDE;
virtual bool validate(bool isValid) SK_OVERRIDE;
+ virtual bool isValid() const SK_OVERRIDE;
private:
bool readArray(void* value, size_t size, size_t elementSize);
SkModeColorFilter(SkFlattenableReadBuffer& buffer) {
fColor = buffer.readColor();
fMode = (SkXfermode::Mode)buffer.readUInt();
- this->updateCache();
- buffer.validate(SkIsValidMode(fMode));
+ if (buffer.isValid()) {
+ this->updateCache();
+ buffer.validate(SkIsValidMode(fMode));
+ }
}
private:
SkColorMatrixFilter::SkColorMatrixFilter(SkFlattenableReadBuffer& buffer)
: INHERITED(buffer) {
SkASSERT(buffer.getArrayCount() == 20);
- buffer.readScalarArray(fMatrix.fMat, 20);
- this->initState(fMatrix.fMat);
- for (int i = 0; i < 20; ++i) {
- buffer.validate(SkScalarIsFinite(fMatrix.fMat[i]));
+ if (buffer.readScalarArray(fMatrix.fMat, 20)) {
+ this->initState(fMatrix.fMat);
}
}
int nbInputs = countInputs();
size_t size = nbInputs * sizeof(fModes[0]);
SkASSERT(buffer.getArrayCount() == size);
- buffer.readByteArray(fModes, size);
- for (int i = 0; i < nbInputs; ++i) {
- buffer.validate(SkIsValidMode((SkXfermode::Mode)fModes[i]));
+ if (buffer.readByteArray(fModes, size)) {
+ for (int i = 0; i < nbInputs; ++i) {
+ buffer.validate(SkIsValidMode((SkXfermode::Mode)fModes[i]));
+ }
}
} else {
fModes = 0;
: INHERITED(1, buffer) {
buffer.readRect(&fSrcRect);
buffer.readRect(&fDstRect);
- buffer.validate(SkIsValidRect(fSrcRect) && SkIsValidRect(fDstRect));
+ buffer.validate(buffer.isValid() && SkIsValidRect(fSrcRect) && SkIsValidRect(fDstRect));
}
void SkTileImageFilter::flatten(SkFlattenableWriteBuffer& buffer) const {
SkValidatingReadBuffer buffer(dataWritten, bytesWritten - 4);
T obj;
SerializationUtils<T>::Read(buffer, &obj);
- REPORTER_ASSERT(reporter, !buffer.validate(true));
+ REPORTER_ASSERT(reporter, !buffer.isValid());
// Make sure this succeeds when it should
SkValidatingReadBuffer buffer2(dataWritten, bytesWritten);
SerializationUtils<T>::Read(buffer2, &obj2);
const unsigned char* peekAfter = static_cast<const unsigned char*>(buffer2.skip(0));
// This should have succeeded, since there are enough bytes to read this
- REPORTER_ASSERT(reporter, buffer2.validate(true));
+ REPORTER_ASSERT(reporter, buffer2.isValid());
REPORTER_ASSERT(reporter, static_cast<size_t>(peekAfter - peekBefore) == bytesWritten);
TestAlignment(testObj, reporter);
SkValidatingReadBuffer buffer(dataWritten, bytesWritten - 4);
T* obj = NULL;
SerializationUtils<T>::Read(buffer, &obj);
- REPORTER_ASSERT(reporter, !buffer.validate(true));
+ REPORTER_ASSERT(reporter, !buffer.isValid());
REPORTER_ASSERT(reporter, NULL == obj);
// Make sure this succeeds when it should
const unsigned char* peekAfter = static_cast<const unsigned char*>(buffer2.skip(0));
if (shouldSucceed) {
// This should have succeeded, since there are enough bytes to read this
- REPORTER_ASSERT(reporter, buffer2.validate(true));
+ REPORTER_ASSERT(reporter, buffer2.isValid());
REPORTER_ASSERT(reporter, static_cast<size_t>(peekAfter - peekBefore) == bytesWritten);
REPORTER_ASSERT(reporter, NULL != obj2);
} else {
// If the deserialization was supposed to fail, make sure it did
- REPORTER_ASSERT(reporter, !buffer.validate(true));
+ REPORTER_ASSERT(reporter, !buffer.isValid());
REPORTER_ASSERT(reporter, NULL == obj2);
}