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:
parent
85834d1265
commit
61e30b2e81
@ -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();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user