| Index: src/core/SkValidatingReadBuffer.cpp
|
| diff --git a/src/core/SkValidatingReadBuffer.cpp b/src/core/SkValidatingReadBuffer.cpp
|
| index 323273d131a25d80a84d0aa671aea023f1c9f501..9f094f9617f1161361452a3b8d56a6d285967a92 100644
|
| --- a/src/core/SkValidatingReadBuffer.cpp
|
| +++ b/src/core/SkValidatingReadBuffer.cpp
|
| @@ -20,8 +20,16 @@ SkValidatingReadBuffer::SkValidatingReadBuffer(const void* data, size_t size) :
|
| SkValidatingReadBuffer::~SkValidatingReadBuffer() {
|
| }
|
|
|
| +void SkValidatingReadBuffer::validate(bool isValid) {
|
| + if (!fError && !isValid) {
|
| + // When an error is found, send the read cursor to the end of the stream
|
| + fReader.skip(fReader.available());
|
| + fError = true;
|
| + }
|
| +}
|
| +
|
| void SkValidatingReadBuffer::setMemory(const void* data, size_t size) {
|
| - fError = fError || !IsPtrAlign4(data) || (SkAlign4(size) != size);
|
| + this->validate(IsPtrAlign4(data) && (SkAlign4(size) == size));
|
| if (!fError) {
|
| fReader.setMemory(data, size);
|
| }
|
| @@ -30,7 +38,7 @@ void SkValidatingReadBuffer::setMemory(const void* data, size_t size) {
|
| const void* SkValidatingReadBuffer::skip(size_t size) {
|
| size_t inc = SkAlign4(size);
|
| const void* addr = fReader.peek();
|
| - fError = fError || !IsPtrAlign4(addr) || !fReader.isAvailable(inc);
|
| + this->validate(IsPtrAlign4(addr) && fReader.isAvailable(inc));
|
| if (!fError) {
|
| fReader.skip(size);
|
| }
|
| @@ -45,9 +53,7 @@ const void* SkValidatingReadBuffer::skip(size_t size) {
|
| bool SkValidatingReadBuffer::readBool() {
|
| uint32_t value = this->readInt();
|
| // Boolean value should be either 0 or 1
|
| - if (value & ~1) {
|
| - fError = true;
|
| - }
|
| + this->validate(!(value & ~1));
|
| return value != 0;
|
| }
|
|
|
| @@ -61,13 +67,13 @@ SkFixed SkValidatingReadBuffer::readFixed() {
|
|
|
| int32_t SkValidatingReadBuffer::readInt() {
|
| const size_t inc = sizeof(int32_t);
|
| - fError = fError || !IsPtrAlign4(fReader.peek()) || !fReader.isAvailable(inc);
|
| + this->validate(IsPtrAlign4(fReader.peek()) && fReader.isAvailable(inc));
|
| return fError ? 0 : fReader.readInt();
|
| }
|
|
|
| SkScalar SkValidatingReadBuffer::readScalar() {
|
| const size_t inc = sizeof(SkScalar);
|
| - fError = fError || !IsPtrAlign4(fReader.peek()) || !fReader.isAvailable(inc);
|
| + this->validate(IsPtrAlign4(fReader.peek()) && fReader.isAvailable(inc));
|
| return fError ? 0 : fReader.readScalar();
|
| }
|
|
|
| @@ -87,7 +93,7 @@ void SkValidatingReadBuffer::readString(SkString* string) {
|
| // skip over the string + '\0' and then pad to a multiple of 4
|
| const size_t alignedSize = SkAlign4(len + 1);
|
| this->skip(alignedSize);
|
| - fError = fError || (cptr[len] != '\0');
|
| + this->validate(cptr[len] == '\0');
|
| if (!fError) {
|
| string->set(cptr, len);
|
| }
|
| @@ -95,7 +101,7 @@ void SkValidatingReadBuffer::readString(SkString* string) {
|
|
|
| void* SkValidatingReadBuffer::readEncodedString(size_t* length, SkPaint::TextEncoding encoding) {
|
| const int32_t encodingType = fReader.readInt();
|
| - fError = fError || (encodingType != encoding);
|
| + this->validate(encodingType == encoding);
|
| *length = this->readInt();
|
| const void* ptr = this->skip(SkAlign4(*length));
|
| void* data = NULL;
|
| @@ -113,7 +119,7 @@ void SkValidatingReadBuffer::readPoint(SkPoint* point) {
|
|
|
| void SkValidatingReadBuffer::readMatrix(SkMatrix* matrix) {
|
| const size_t size = matrix->readFromMemory(fReader.peek());
|
| - fError = fError || (SkAlign4(size) != size);
|
| + this->validate(SkAlign4(size) == size);
|
| if (!fError) {
|
| (void)this->skip(size);
|
| }
|
| @@ -135,7 +141,7 @@ void SkValidatingReadBuffer::readRect(SkRect* rect) {
|
|
|
| void SkValidatingReadBuffer::readRegion(SkRegion* region) {
|
| const size_t size = region->readFromMemory(fReader.peek());
|
| - fError = fError || (SkAlign4(size) != size);
|
| + this->validate(SkAlign4(size) == size);
|
| if (!fError) {
|
| (void)this->skip(size);
|
| }
|
| @@ -143,64 +149,43 @@ void SkValidatingReadBuffer::readRegion(SkRegion* region) {
|
|
|
| void SkValidatingReadBuffer::readPath(SkPath* path) {
|
| const size_t size = path->readFromMemory(fReader.peek());
|
| - fError = fError || (SkAlign4(size) != size);
|
| + this->validate(SkAlign4(size) == size);
|
| if (!fError) {
|
| (void)this->skip(size);
|
| }
|
| }
|
|
|
| -uint32_t SkValidatingReadBuffer::readByteArray(void* value) {
|
| - const uint32_t length = this->readUInt();
|
| - const void* ptr = this->skip(SkAlign4(length));
|
| +bool SkValidatingReadBuffer::readArray(void* value, size_t size, size_t elementSize) {
|
| + const uint32_t count = this->getArrayCount();
|
| + this->validate(size == count);
|
| + (void)this->skip(sizeof(uint32_t)); // Skip array count
|
| + const size_t byteLength = count * elementSize;
|
| + const void* ptr = this->skip(SkAlign4(byteLength));
|
| if (!fError) {
|
| - memcpy(value, ptr, length);
|
| - return length;
|
| + memcpy(value, ptr, byteLength);
|
| + return true;
|
| }
|
| - return 0;
|
| + return false;
|
| }
|
|
|
| -uint32_t SkValidatingReadBuffer::readColorArray(SkColor* colors) {
|
| - const uint32_t count = this->readUInt();
|
| - const uint32_t byteLength = count * sizeof(SkColor);
|
| - const void* ptr = this->skip(SkAlign4(byteLength));
|
| - if (!fError) {
|
| - memcpy(colors, ptr, byteLength);
|
| - return count;
|
| - }
|
| - return 0;
|
| +bool SkValidatingReadBuffer::readByteArray(void* value, size_t size) {
|
| + return readArray(static_cast<unsigned char*>(value), size, sizeof(unsigned char));
|
| }
|
|
|
| -uint32_t SkValidatingReadBuffer::readIntArray(int32_t* values) {
|
| - const uint32_t count = this->readUInt();
|
| - const uint32_t byteLength = count * sizeof(int32_t);
|
| - const void* ptr = this->skip(SkAlign4(byteLength));
|
| - if (!fError) {
|
| - memcpy(values, ptr, byteLength);
|
| - return count;
|
| - }
|
| - return 0;
|
| +bool SkValidatingReadBuffer::readColorArray(SkColor* colors, size_t size) {
|
| + return readArray(colors, size, sizeof(SkColor));
|
| }
|
|
|
| -uint32_t SkValidatingReadBuffer::readPointArray(SkPoint* points) {
|
| - const uint32_t count = this->readUInt();
|
| - const uint32_t byteLength = count * sizeof(SkPoint);
|
| - const void* ptr = this->skip(SkAlign4(byteLength));
|
| - if (!fError) {
|
| - memcpy(points, ptr, byteLength);
|
| - return count;
|
| - }
|
| - return 0;
|
| +bool SkValidatingReadBuffer::readIntArray(int32_t* values, size_t size) {
|
| + return readArray(values, size, sizeof(int32_t));
|
| }
|
|
|
| -uint32_t SkValidatingReadBuffer::readScalarArray(SkScalar* values) {
|
| - const uint32_t count = this->readUInt();
|
| - const uint32_t byteLength = count * sizeof(SkScalar);
|
| - const void* ptr = this->skip(SkAlign4(byteLength));
|
| - if (!fError) {
|
| - memcpy(values, ptr, byteLength);
|
| - return count;
|
| - }
|
| - return 0;
|
| +bool SkValidatingReadBuffer::readPointArray(SkPoint* points, size_t size) {
|
| + return readArray(points, size, sizeof(SkPoint));
|
| +}
|
| +
|
| +bool SkValidatingReadBuffer::readScalarArray(SkScalar* values, size_t size) {
|
| + return readArray(values, size, sizeof(SkScalar));
|
| }
|
|
|
| uint32_t SkValidatingReadBuffer::getArrayCount() {
|
| @@ -212,12 +197,17 @@ void SkValidatingReadBuffer::readBitmap(SkBitmap* bitmap) {
|
| const int height = this->readInt();
|
| const size_t length = this->readUInt();
|
| // A size of zero means the SkBitmap was simply flattened.
|
| - fError = fError || (length != 0);
|
| + this->validate(length == 0);
|
| if (fError) {
|
| return;
|
| }
|
| bitmap->unflatten(*this);
|
| - fError = fError || (bitmap->width() != width) || (bitmap->height() != height);
|
| + this->validate((bitmap->width() == width) && (bitmap->height() == height));
|
| +}
|
| +
|
| +SkTypeface* SkValidatingReadBuffer::readTypeface() {
|
| + // TODO: Implement this (securely) when needed
|
| + return NULL;
|
| }
|
|
|
| SkFlattenable* SkValidatingReadBuffer::readFlattenable(SkFlattenable::Type type) {
|
| @@ -248,7 +238,7 @@ SkFlattenable* SkValidatingReadBuffer::readFlattenable(SkFlattenable::Type type)
|
| obj = (*factory)(*this);
|
| // check that we read the amount we expected
|
| uint32_t sizeRead = fReader.offset() - offset;
|
| - fError = fError || (sizeRecorded != sizeRead);
|
| + this->validate(sizeRecorded == sizeRead);
|
| if (fError) {
|
| // we could try to fix up the offset...
|
| delete obj;
|
|
|