diff options
author | 2017-02-21 14:18:01 -0500 | |
---|---|---|
committer | 2017-02-21 21:23:48 +0000 | |
commit | 709b02534681f8ab8d17f144713f276e10d13385 (patch) | |
tree | da4df3f2623a111fb83347180d9cbe632b57a41f /src/core | |
parent | c5ca7f955bfeb28eadf907da1b8399cad4037d1a (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.cpp | 17 |
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) { |