aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Mike Reed <reed@google.com>2017-01-03 13:58:21 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-01-03 19:31:26 +0000
commite3374d68932ce5bd1e6a50b05a6764a543c00c39 (patch)
tree3c972d188c1435fe796304b6c693062f46d551e9 /src
parentb0b625b79605ab0a18aa038f3f87e88da2441c16 (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.cpp43
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