abort op early if path isn't parseable

TBR=
BUG=419649

Review URL: https://codereview.chromium.org/623943002
This commit is contained in:
caryclark 2014-10-03 05:36:27 -07:00 committed by Commit bot
parent d012877a6d
commit d751ac01a3
3 changed files with 30 additions and 5 deletions

View File

@ -27,6 +27,8 @@ public:
init();
}
void addOperand(const SkPath& path);
void complete() {
if (fCurrentContour && fCurrentContour->segments().count()) {
fCurrentContour->complete();
@ -34,13 +36,10 @@ public:
}
}
SkPathOpsMask xorMask() const {
return fXorMask[fOperand];
}
void addOperand(const SkPath& path);
bool finish();
void init();
bool unparseable() const { return fUnparseable; }
SkPathOpsMask xorMask() const { return fXorMask[fOperand]; }
private:
void closeContour(const SkPoint& curveEnd, const SkPoint& curveStart);

View File

@ -270,6 +270,9 @@ bool Op(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result) {
SkTArray<SkOpContour> contours;
// FIXME: add self-intersecting cubics' T values to segment
SkOpEdgeBuilder builder(*minuend, contours);
if (builder.unparseable()) {
return false;
}
const int xorMask = builder.xorMask();
builder.addOperand(*subtrahend);
if (!builder.finish()) {

View File

@ -3925,7 +3925,30 @@ path.close();
testPathFailOp(reporter, path1, path2, (SkPathOp) 2, filename);
}
static void fuzz1(skiatest::Reporter* reporter, const char* filename) {
SkPath path;
path.setFillType((SkPath::FillType) 0);
path.moveTo(SkBits2Float(0x7f800000), SkBits2Float(0x7f800000));
path.quadTo(SkBits2Float(0x7f800000), SkBits2Float(0x7f800000), SkBits2Float(0x7f800000), SkBits2Float(0x7f800000));
path.quadTo(SkBits2Float(0x7f800000), SkBits2Float(0x7f800000), SkBits2Float(0x7f800000), SkBits2Float(0x7f800000));
path.quadTo(SkBits2Float(0xffc00000), SkBits2Float(0x7f800000), SkBits2Float(0xffc00000), SkBits2Float(0x7f800000));
path.quadTo(SkBits2Float(0xff000001), SkBits2Float(0x7f800000), SkBits2Float(0xff000001), SkBits2Float(0x7f800000));
path.quadTo(SkBits2Float(0xff000001), SkBits2Float(0xffc00000), SkBits2Float(0xffc00000), SkBits2Float(0xffc00000));
path.quadTo(SkBits2Float(0xffc00000), SkBits2Float(0xff000001), SkBits2Float(0x7f800000), SkBits2Float(0xff000001));
path.quadTo(SkBits2Float(0x7f800000), SkBits2Float(0xff000001), SkBits2Float(0x7f800000), SkBits2Float(0xffc00000));
path.quadTo(SkBits2Float(0x7f800000), SkBits2Float(0xffc00000), SkBits2Float(0x7f800000), SkBits2Float(0x7f800000));
path.close();
SkPath path1(path);
path.reset();
path.setFillType((SkPath::FillType) 0);
SkPath path2(path);
testPathFailOp(reporter, path1, path2, (SkPathOp) 2, filename);
}
static struct TestDesc failTests[] = {
TEST(fuzz1),
TEST(fuzz714),
TEST(fuzz487a),
TEST(fuzz487b),