diff options
author | 2017-01-03 13:58:21 -0500 | |
---|---|---|
committer | 2017-01-03 19:31:26 +0000 | |
commit | e3374d68932ce5bd1e6a50b05a6764a543c00c39 (patch) | |
tree | 3c972d188c1435fe796304b6c693062f46d551e9 /src | |
parent | b0b625b79605ab0a18aa038f3f87e88da2441c16 (diff) |
validate deserialized path verbs
BUG=676755
Change-Id: Ie9bd70d3a130c53737756587f73c9dce4a6bcb6d
Reviewed-on: https://skia-review.googlesource.com/6529
Commit-Queue: Mike Reed <reed@google.com>
Reviewed-by: Cary Clark <caryclark@google.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/core/SkPathRef.cpp | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/src/core/SkPathRef.cpp b/src/core/SkPathRef.cpp index ef051f7e84..55ee9914fa 100644 --- a/src/core/SkPathRef.cpp +++ b/src/core/SkPathRef.cpp @@ -186,6 +186,38 @@ void SkPathRef::CreateTransformedCopy(sk_sp<SkPathRef>* dst, SkDEBUGCODE((*dst)->validate();) } +// Given the verb array, deduce the required number of pts and conics, +// or if an invalid verb is encountered, return false. +static bool deduce_pts_conics(const uint8_t verbs[], int vCount, int* ptCountPtr, + int* conicCountPtr) { + int ptCount = 0; + int conicCount = 0; + for (int i = 0; i < vCount; ++i) { + switch (verbs[i]) { + case SkPath::kMove_Verb: + case SkPath::kLine_Verb: + ptCount += 1; + break; + case SkPath::kConic_Verb: + conicCount += 1; + // fall-through + case SkPath::kQuad_Verb: + ptCount += 2; + break; + case SkPath::kCubic_Verb: + ptCount += 3; + break; + case SkPath::kClose_Verb: + break; + default: + return false; + } + } + *ptCountPtr = ptCount; + *conicCountPtr = conicCount; + return true; +} + SkPathRef* SkPathRef::CreateFromBuffer(SkRBuffer* buffer) { SkPathRef* ref = new SkPathRef; @@ -231,6 +263,17 @@ SkPathRef* SkPathRef::CreateFromBuffer(SkRBuffer* buffer) { delete ref; return nullptr; } + + // Check that the verbs are valid, and imply the correct number of pts and conics + { + int pCount, cCount; + if (!deduce_pts_conics(ref->verbsMemBegin(), ref->countVerbs(), &pCount, &cCount) || + pCount != ref->countPoints() || cCount != ref->fConicWeights.count()) { + delete ref; + return nullptr; + } + } + ref->fBoundsIsDirty = false; // resetToSize clears fSegmentMask and fIsOval |