validate paint setters in readbuffer
Bug: skia:7425 Change-Id: I55213bc206cf5cfb8cbf4fbe8a682efd6eae59fa Reviewed-on: https://skia-review.googlesource.com/96860 Commit-Queue: Mike Reed <reed@google.com> Reviewed-by: Herb Derby <herb@google.com>
This commit is contained in:
parent
9ca27849d8
commit
e97e792c79
@ -577,7 +577,7 @@ can reconstitute the paint at a later time.
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
#Method void unflatten(SkReadBuffer& buffer)
|
||||
#Method bool unflatten(SkReadBuffer& buffer)
|
||||
|
||||
Populates Paint, typically from a serialized stream, created by calling
|
||||
flatten() at an earlier time.
|
||||
@ -587,6 +587,8 @@ by the client.
|
||||
|
||||
#Param buffer serialized data describing Paint content ##
|
||||
|
||||
#Return false if the buffer contained invalid data for initializing the paint. ##
|
||||
|
||||
# why is unflatten() public?
|
||||
#Bug 6172 ##
|
||||
|
||||
|
@ -177,8 +177,10 @@ public:
|
||||
by the client.
|
||||
|
||||
@param buffer serialized data describing SkPaint content
|
||||
@return false if the buffer contained invalid data to initialize the paint, in which case
|
||||
the paint will be reset().
|
||||
*/
|
||||
void unflatten(SkReadBuffer& buffer);
|
||||
bool unflatten(SkReadBuffer& buffer);
|
||||
|
||||
/** Sets all SkPaint contents to their initial values. This is equivalent to replacing
|
||||
SkPaint with the result of SkPaint().
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "SkPaintDefaults.h"
|
||||
#include "SkPathEffect.h"
|
||||
#include "SkRasterizer.h"
|
||||
#include "SkSafeRange.h"
|
||||
#include "SkScalar.h"
|
||||
#include "SkScalerContext.h"
|
||||
#include "SkShader.h"
|
||||
@ -1911,7 +1912,9 @@ void SkPaint::flatten(SkWriteBuffer& buffer) const {
|
||||
}
|
||||
}
|
||||
|
||||
void SkPaint::unflatten(SkReadBuffer& buffer) {
|
||||
bool SkPaint::unflatten(SkReadBuffer& buffer) {
|
||||
SkSafeRange safe;
|
||||
|
||||
this->setTextSize(buffer.readScalar());
|
||||
this->setTextScaleX(buffer.readScalar());
|
||||
this->setTextSkewX(buffer.readScalar());
|
||||
@ -1922,11 +1925,11 @@ void SkPaint::unflatten(SkReadBuffer& buffer) {
|
||||
unsigned flatFlags = unpack_paint_flags(this, buffer.readUInt());
|
||||
|
||||
uint32_t tmp = buffer.readUInt();
|
||||
this->setStrokeCap(static_cast<Cap>((tmp >> 24) & 0xFF));
|
||||
this->setStrokeJoin(static_cast<Join>((tmp >> 16) & 0xFF));
|
||||
this->setStyle(static_cast<Style>((tmp >> 12) & 0xF));
|
||||
this->setTextEncoding(static_cast<TextEncoding>((tmp >> 8) & 0xF));
|
||||
this->setBlendMode((SkBlendMode)(tmp & 0xFF));
|
||||
this->setStrokeCap(safe.checkLE((tmp >> 24) & 0xFF, kLast_Cap));
|
||||
this->setStrokeJoin(safe.checkLE((tmp >> 16) & 0xFF, kLast_Join));
|
||||
this->setStyle(safe.checkLE((tmp >> 12) & 0xF, kStrokeAndFill_Style));
|
||||
this->setTextEncoding(safe.checkLE((tmp >> 8) & 0xF, kGlyphID_TextEncoding));
|
||||
this->setBlendMode(safe.checkLE(tmp & 0xFF, SkBlendMode::kLastMode));
|
||||
|
||||
if (flatFlags & kHasTypeface_FlatFlag) {
|
||||
this->setTypeface(buffer.readTypeface());
|
||||
@ -1951,6 +1954,12 @@ void SkPaint::unflatten(SkReadBuffer& buffer) {
|
||||
this->setLooper(nullptr);
|
||||
this->setImageFilter(nullptr);
|
||||
}
|
||||
|
||||
if (!buffer.validate(safe)) {
|
||||
this->reset();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -505,7 +505,9 @@ bool SkPictureData::parseBufferTag(SkReadBuffer& buffer, uint32_t tag, uint32_t
|
||||
const int count = SkToInt(size);
|
||||
fPaints.reset(count);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
buffer.readPaint(&fPaints[i]);
|
||||
if (!buffer.readPaint(&fPaints[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case SK_PICT_PATH_BUFFER_TAG:
|
||||
|
@ -134,7 +134,7 @@ public:
|
||||
void readRegion(SkRegion* region);
|
||||
|
||||
void readPath(SkPath* path);
|
||||
virtual void readPaint(SkPaint* paint) { paint->unflatten(*this); }
|
||||
virtual bool readPaint(SkPaint* paint) { return paint->unflatten(*this); }
|
||||
|
||||
SkFlattenable* readFlattenable(SkFlattenable::Type);
|
||||
template <typename T> sk_sp<T> readFlattenable() {
|
||||
|
37
src/core/SkSafeRange.h
Normal file
37
src/core/SkSafeRange.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2018 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkSafeRange_DEFINED
|
||||
#define SkSafeRange_DEFINED
|
||||
|
||||
// SkSafeRange always check that a series of operations are in-range.
|
||||
// This check is sticky, so that if any one operation fails, the object will remember that and
|
||||
// return false from ok().
|
||||
|
||||
class SkSafeRange {
|
||||
public:
|
||||
operator bool() const { return fOK; }
|
||||
|
||||
bool ok() const { return fOK; }
|
||||
|
||||
// checks 0 <= value <= max.
|
||||
// On success, returns value
|
||||
// On failure, returns 0 and sets ok() to false
|
||||
template <typename T> T checkLE(uint64_t value, T max) {
|
||||
SkASSERT(static_cast<int64_t>(max) >= 0);
|
||||
if (value > static_cast<uint64_t>(max)) {
|
||||
fOK = false;
|
||||
value = 0;
|
||||
}
|
||||
return static_cast<T>(value);
|
||||
}
|
||||
|
||||
private:
|
||||
bool fOK = true;
|
||||
};
|
||||
|
||||
#endif
|
@ -207,8 +207,9 @@ public:
|
||||
return factory;
|
||||
}
|
||||
|
||||
void readPaint(SkPaint* paint) override {
|
||||
bool readPaint(SkPaint* paint) override {
|
||||
*paint = read_paint(*this);
|
||||
return this->isValid();
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user