aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
authorGravatar Hal Canary <halcanary@google.com>2017-02-21 14:18:01 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-02-21 21:23:48 +0000
commit709b02534681f8ab8d17f144713f276e10d13385 (patch)
treeda4df3f2623a111fb83347180d9cbe632b57a41f /src/core
parentc5ca7f955bfeb28eadf907da1b8399cad4037d1a (diff)
SkPath.readFromMemory: check for error case
Fuzzing can produce inconsistant data, such as flags or bounds. Also, use std::unique_ptr to reduce the need for calling `delete`. BUG=skia:6262 BUG=skia:6263 Change-Id: I1de6b5f764cda346bb3cd5cd4698816b6b68f395 Reviewed-on: https://skia-review.googlesource.com/8812 Commit-Queue: Hal Canary <halcanary@google.com> Reviewed-by: Cary Clark <caryclark@google.com>
Diffstat (limited to 'src/core')
-rw-r--r--src/core/SkPathRef.cpp17
1 files changed, 11 insertions, 6 deletions
diff --git a/src/core/SkPathRef.cpp b/src/core/SkPathRef.cpp
index 55ee9914fa..f0fda2703b 100644
--- a/src/core/SkPathRef.cpp
+++ b/src/core/SkPathRef.cpp
@@ -219,11 +219,10 @@ static bool deduce_pts_conics(const uint8_t verbs[], int vCount, int* ptCountPtr
}
SkPathRef* SkPathRef::CreateFromBuffer(SkRBuffer* buffer) {
- SkPathRef* ref = new SkPathRef;
+ std::unique_ptr<SkPathRef> ref(new SkPathRef);
int32_t packed;
if (!buffer->readS32(&packed)) {
- delete ref;
return nullptr;
}
@@ -231,6 +230,10 @@ SkPathRef* SkPathRef::CreateFromBuffer(SkRBuffer* buffer) {
uint8_t segmentMask = (packed >> kSegmentMask_SerializationShift) & 0xF;
bool isOval = (packed >> kIsOval_SerializationShift) & 1;
bool isRRect = (packed >> kIsRRect_SerializationShift) & 1;
+ if (isOval && isRRect) {
+ // Fuzzing generates data with both oval and rrect flags set; abort early in this case/
+ return nullptr;
+ }
bool rrectOrOvalIsCCW = (packed >> kRRectOrOvalIsCCW_SerializationShift) & 1;
unsigned rrectOrOvalStartIdx = (packed >> kRRectOrOvalStartIdx_SerializationShift) & 0x7;
@@ -247,7 +250,6 @@ SkPathRef* SkPathRef::CreateFromBuffer(SkRBuffer* buffer) {
static_cast<size_t>(maxPtrDiff) ||
!buffer->readS32(&conicCount) ||
conicCount < 0) {
- delete ref;
return nullptr;
}
@@ -260,7 +262,6 @@ SkPathRef* SkPathRef::CreateFromBuffer(SkRBuffer* buffer) {
!buffer->read(ref->fPoints, pointCount * sizeof(SkPoint)) ||
!buffer->read(ref->fConicWeights.begin(), conicCount * sizeof(SkScalar)) ||
!buffer->read(&ref->fBounds, sizeof(SkRect))) {
- delete ref;
return nullptr;
}
@@ -269,7 +270,11 @@ SkPathRef* SkPathRef::CreateFromBuffer(SkRBuffer* buffer) {
int pCount, cCount;
if (!deduce_pts_conics(ref->verbsMemBegin(), ref->countVerbs(), &pCount, &cCount) ||
pCount != ref->countPoints() || cCount != ref->fConicWeights.count()) {
- delete ref;
+ return nullptr;
+ }
+ // Check that the bounds match the serialized bounds.
+ SkRect bounds;
+ if (ComputePtBounds(&bounds, *ref) != SkToBool(ref->fIsFinite) || bounds != ref->fBounds) {
return nullptr;
}
}
@@ -282,7 +287,7 @@ SkPathRef* SkPathRef::CreateFromBuffer(SkRBuffer* buffer) {
ref->fIsRRect = isRRect;
ref->fRRectOrOvalIsCCW = rrectOrOvalIsCCW;
ref->fRRectOrOvalStartIdx = rrectOrOvalStartIdx;
- return ref;
+ return ref.release();
}
void SkPathRef::Rewind(sk_sp<SkPathRef>* pathRef) {