aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Mike Reed <reed@google.com>2018-02-21 20:58:33 -0500
committerGravatar Mike Reed <reed@google.com>2018-02-22 14:48:44 +0000
commit61e30b2e81fe8d02d20978daeff28bc06ba584e7 (patch)
tree4c45b95e9eca0cb90bd2bb55163f16f6b4ca0ef9 /src
parent85834d1265d4b7ae8cb737639af3892b4c11ce12 (diff)
add checks for enough data in path deserialization
Bug: oss-fuzz:6501 Change-Id: Ie77d57268947be2cc56f846ce21f154e0d469112 Reviewed-on: https://skia-review.googlesource.com/109320 Commit-Queue: Mike Reed <reed@google.com> Reviewed-by: Mike Klein <mtklein@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/core/SkPath_serial.cpp47
1 files changed, 41 insertions, 6 deletions
diff --git a/src/core/SkPath_serial.cpp b/src/core/SkPath_serial.cpp
index d4983fc8a7..636775538b 100644
--- a/src/core/SkPath_serial.cpp
+++ b/src/core/SkPath_serial.cpp
@@ -222,21 +222,56 @@ size_t SkPath::readFromMemory_EQ4(const void* storage, size_t length) {
}
SkASSERT(buffer.pos() <= length);
+#define CHECK_POINTS_CONICS(p, c) \
+ do { \
+ if (p && ((pts -= p) < 0)) { \
+ return 0; \
+ } \
+ if (c && ((cnx -= c) < 0)) { \
+ return 0; \
+ } \
+ } while (0)
+
SkPath tmp;
tmp.setFillType(extract_filltype(packed));
tmp.incReserve(pts);
for (int i = vbs - 1; i >= 0; --i) {
switch (verbs[i]) {
- case kMove_Verb: tmp.moveTo(*points++); break;
- case kLine_Verb: tmp.lineTo(*points++); break;
- case kQuad_Verb: tmp.quadTo(points[0], points[1]); points += 2; break;
- case kConic_Verb: tmp.conicTo(points[0], points[1], *conics++); points += 2; break;
- case kCubic_Verb: tmp.cubicTo(points[0], points[1], points[2]); points += 3; break;
- case kClose_Verb: tmp.close(); break;
+ case kMove_Verb:
+ CHECK_POINTS_CONICS(1, 0);
+ tmp.moveTo(*points++);
+ break;
+ case kLine_Verb:
+ CHECK_POINTS_CONICS(1, 0);
+ tmp.lineTo(*points++);
+ break;
+ case kQuad_Verb:
+ CHECK_POINTS_CONICS(2, 0);
+ tmp.quadTo(points[0], points[1]);
+ points += 2;
+ break;
+ case kConic_Verb:
+ CHECK_POINTS_CONICS(2, 1);
+ tmp.conicTo(points[0], points[1], *conics++);
+ points += 2;
+ break;
+ case kCubic_Verb:
+ CHECK_POINTS_CONICS(3, 0);
+ tmp.cubicTo(points[0], points[1], points[2]);
+ points += 3;
+ break;
+ case kClose_Verb:
+ tmp.close();
+ break;
default:
return 0; // bad verb
}
}
+#undef CHECK_POINTS_CONICS
+ if (pts || cnx) {
+ return 0; // leftover points and/or conics
+ }
+
*this = std::move(tmp);
return buffer.pos();
}