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>
This commit is contained in:
Mike Reed 2018-02-21 20:58:33 -05:00
parent 85834d1265
commit 61e30b2e81

View File

@ -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();
}