From: caryclark Date: Tue, 28 Jun 2016 16:23:57 +0000 (-0700) Subject: fix fuzz bugs X-Git-Tag: submit/tizen/20180928.044319~129^2~38 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3f0753d3eccece8ac7f02f6af36d66a96c3dfb26;p=platform%2Fupstream%2FlibSkiaSharp.git fix fuzz bugs Detect more places where the pathops numerics cause numbers to become nearly identical and subsequently fail. These tests have extreme inputs and cannot succeed. Also remove the expectSuccess parameter from PathOpsDebug and check instead in the test framework. R=mbarbella@chromium.org TBR=reed@google.com BUG=623072,623022 GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2103513002 Review-Url: https://codereview.chromium.org/2103513002 --- diff --git a/src/pathops/SkDConicLineIntersection.cpp b/src/pathops/SkDConicLineIntersection.cpp index 2d906072fa..710647236c 100644 --- a/src/pathops/SkDConicLineIntersection.cpp +++ b/src/pathops/SkDConicLineIntersection.cpp @@ -157,7 +157,9 @@ public: double conicT = roots[index]; SkDPoint pt = fConic.ptAtT(conicT); SkDEBUGCODE_(double conicVals[] = { fConic[0].fX, fConic[1].fX, fConic[2].fX }); - SkASSERT(close_to(pt.fX, axisIntercept, conicVals)); + SkASSERT((fIntersections->debugGlobalState() && + fIntersections->debugGlobalState()->debugSkipAssert()) || + close_to(pt.fX, axisIntercept, conicVals)); double lineT = (pt.fY - top) / (bottom - top); if (this->pinTs(&conicT, &lineT, &pt, kPointInitialized) && this->uniqueAnswer(conicT, pt)) { diff --git a/src/pathops/SkOpCoincidence.cpp b/src/pathops/SkOpCoincidence.cpp index b72bd6cb37..4b46e685ee 100755 --- a/src/pathops/SkOpCoincidence.cpp +++ b/src/pathops/SkOpCoincidence.cpp @@ -326,34 +326,41 @@ bool SkOpCoincidence::addMissing(SkChunkAlloc* allocator) { return added; } -void SkOpCoincidence::addOverlap(SkOpSegment* seg1, SkOpSegment* seg1o, SkOpSegment* seg2, +bool SkOpCoincidence::addOverlap(SkOpSegment* seg1, SkOpSegment* seg1o, SkOpSegment* seg2, SkOpSegment* seg2o, SkOpPtT* overS, SkOpPtT* overE, SkChunkAlloc* allocator) { SkOpPtT* s1 = overS->find(seg1); SkOpPtT* e1 = overE->find(seg1); + if (approximately_equal_half(s1->fT, e1->fT)) { + return false; + } if (!s1->starter(e1)->span()->upCast()->windValue()) { s1 = overS->find(seg1o); e1 = overE->find(seg1o); if (!s1->starter(e1)->span()->upCast()->windValue()) { - return; + return true; } } SkOpPtT* s2 = overS->find(seg2); SkOpPtT* e2 = overE->find(seg2); + if (approximately_equal_half(s2->fT, e2->fT)) { + return false; + } if (!s2->starter(e2)->span()->upCast()->windValue()) { s2 = overS->find(seg2o); e2 = overE->find(seg2o); if (!s2->starter(e2)->span()->upCast()->windValue()) { - return; + return true; } } if (s1->segment() == s2->segment()) { - return; + return true; } if (s1->fT > e1->fT) { SkTSwap(s1, e1); SkTSwap(s2, e2); } this->add(s1, e1, s2, e2, allocator); + return true; } bool SkOpCoincidence::contains(const SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd, @@ -540,7 +547,7 @@ bool SkOpCoincidence::expand() { return expanded; } -void SkOpCoincidence::findOverlaps(SkOpCoincidence* overlaps, SkChunkAlloc* allocator) const { +bool SkOpCoincidence::findOverlaps(SkOpCoincidence* overlaps, SkChunkAlloc* allocator) const { overlaps->fHead = overlaps->fTop = nullptr; SkDEBUGCODE_(overlaps->debugSetGlobalState(fDebugState)); SkCoincidentSpans* outer = fHead; @@ -563,18 +570,21 @@ void SkOpCoincidence::findOverlaps(SkOpCoincidence* overlaps, SkChunkAlloc* allo || (outerOpp == innerOpp && SkOpPtT::Overlaps(outer->fOppPtTStart, outer->fOppPtTEnd, inner->fOppPtTStart, inner->fOppPtTEnd, &overlapS, &overlapE))) { - overlaps->addOverlap(outerCoin, outerOpp, innerCoin, innerOpp, - overlapS, overlapE, allocator); + if (!overlaps->addOverlap(outerCoin, outerOpp, innerCoin, innerOpp, + overlapS, overlapE, allocator)) { + return false; + } } } outer = outer->fNext; } + return true; } -void SkOpCoincidence::fixAligned() { +bool SkOpCoincidence::fixAligned() { SkCoincidentSpans* coin = fHead; if (!coin) { - return; + return true; } do { if (coin->fCoinPtTStart->deleted()) { @@ -593,6 +603,12 @@ void SkOpCoincidence::fixAligned() { coin = fHead; SkCoincidentSpans** priorPtr = &fHead; do { + if (coin->fCoinPtTStart == coin->fCoinPtTEnd) { + return false; + } + if (coin->fOppPtTStart == coin->fOppPtTEnd) { + return false; + } if (coin->fCoinPtTStart->collapsed(coin->fCoinPtTEnd) || coin->fOppPtTStart->collapsed(coin->fOppPtTEnd)) { *priorPtr = coin->fNext; @@ -600,6 +616,7 @@ void SkOpCoincidence::fixAligned() { } priorPtr = &coin->fNext; } while ((coin = coin->fNext)); + return true; } void SkOpCoincidence::fixUp(SkOpPtT* deleted, SkOpPtT* kept) { diff --git a/src/pathops/SkOpCoincidence.h b/src/pathops/SkOpCoincidence.h index 344866ff36..1efe6c0613 100644 --- a/src/pathops/SkOpCoincidence.h +++ b/src/pathops/SkOpCoincidence.h @@ -84,8 +84,8 @@ public: bool expand(); bool extend(SkOpPtT* coinPtTStart, SkOpPtT* coinPtTEnd, SkOpPtT* oppPtTStart, SkOpPtT* oppPtTEnd); - void findOverlaps(SkOpCoincidence* , SkChunkAlloc* allocator) const; - void fixAligned(); + bool findOverlaps(SkOpCoincidence* , SkChunkAlloc* allocator) const; + bool fixAligned(); void fixUp(SkOpPtT* deleted, SkOpPtT* kept); bool isEmpty() const { @@ -103,7 +103,7 @@ private: SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd, SkOpPtT* oppPtTStart, const SkOpPtT* oppPtTEnd, SkChunkAlloc* ); - void addOverlap(SkOpSegment* seg1, SkOpSegment* seg1o, SkOpSegment* seg2, SkOpSegment* seg2o, + bool addOverlap(SkOpSegment* seg1, SkOpSegment* seg1o, SkOpSegment* seg2, SkOpSegment* seg2o, SkOpPtT* overS, SkOpPtT* overE, SkChunkAlloc* ); bool debugAddIfMissing(const SkCoincidentSpans* outer, const SkOpPtT* over1s, const SkOpPtT* over1e) const; diff --git a/src/pathops/SkPathOpsCommon.cpp b/src/pathops/SkPathOpsCommon.cpp index 340b306d60..ec8e78d0cb 100644 --- a/src/pathops/SkPathOpsCommon.cpp +++ b/src/pathops/SkPathOpsCommon.cpp @@ -466,7 +466,9 @@ bool HandleCoincidence(SkOpContourHead* contourList, SkOpCoincidence* coincidenc DEBUG_COINCIDENCE_HEALTH(contourList, "moveNearby"); align(contourList); // give all span members common values DEBUG_COINCIDENCE_HEALTH(contourList, "align"); - coincidence->fixAligned(); // aligning may have marked a coincidence pt-t deleted + if (!coincidence->fixAligned()) { // aligning may have marked a coincidence pt-t deleted + return false; + } DEBUG_COINCIDENCE_HEALTH(contourList, "fixAligned"); #if DEBUG_VALIDATE globalState->setPhase(SkOpGlobalState::kIntersecting); @@ -480,7 +482,9 @@ bool HandleCoincidence(SkOpContourHead* contourList, SkOpCoincidence* coincidenc DEBUG_COINCIDENCE_HEALTH(contourList, "moveNearby2"); align(contourList); // give all span members common values DEBUG_COINCIDENCE_HEALTH(contourList, "align2"); - coincidence->fixAligned(); // aligning may have marked a coincidence pt-t deleted + if (!coincidence->fixAligned()) { // aligning may have marked a coincidence pt-t deleted + return false; + } DEBUG_COINCIDENCE_HEALTH(contourList, "fixAligned2"); } #if DEBUG_VALIDATE @@ -520,7 +524,9 @@ bool HandleCoincidence(SkOpContourHead* contourList, SkOpCoincidence* coincidenc DEBUG_COINCIDENCE_HEALTH(contourList, "pairs->apply"); // For each coincident pair that overlaps another, when the receivers (the 1st of the pair) // are different, construct a new pair to resolve their mutual span - pairs->findOverlaps(&overlaps, allocator); + if (!pairs->findOverlaps(&overlaps, allocator)) { + return false; + } DEBUG_COINCIDENCE_HEALTH(contourList, "pairs->findOverlaps"); } while (!overlaps.isEmpty()); calcAngles(contourList, allocator); diff --git a/src/pathops/SkPathOpsCommon.h b/src/pathops/SkPathOpsCommon.h index 856a984ce5..5b4902f53b 100644 --- a/src/pathops/SkPathOpsCommon.h +++ b/src/pathops/SkPathOpsCommon.h @@ -25,8 +25,8 @@ SkOpSegment* FindUndone(SkOpContourHead* , SkOpSpanBase** startPtr, bool FixWinding(SkPath* path); bool SortContourList(SkOpContourHead** , bool evenOdd, bool oppEvenOdd); bool HandleCoincidence(SkOpContourHead* , SkOpCoincidence* , SkChunkAlloc* ); -bool OpDebug(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result, - bool expectSuccess SkDEBUGPARAMS(bool skipAssert) +bool OpDebug(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result + SkDEBUGPARAMS(bool skipAssert) SkDEBUGPARAMS(const char* testName)); #if DEBUG_ACTIVE_SPANS void DebugShowActiveSpans(SkOpContourHead* ); diff --git a/src/pathops/SkPathOpsConic.cpp b/src/pathops/SkPathOpsConic.cpp index 86bad262e3..dd523211de 100644 --- a/src/pathops/SkPathOpsConic.cpp +++ b/src/pathops/SkPathOpsConic.cpp @@ -34,7 +34,10 @@ int SkDConic::FindExtrema(const double src[], SkScalar w, double t[1]) { double tValues[2]; int roots = SkDQuad::RootsValidT(coeff[0], coeff[1], coeff[2], tValues); - SkASSERT(0 == roots || 1 == roots); + // In extreme cases, the number of roots returned can be 2. Pathops + // will fail later on, so there's no advantage to plumbing in an error + // return here. + // SkASSERT(0 == roots || 1 == roots); if (1 == roots) { t[0] = tValues[0]; diff --git a/src/pathops/SkPathOpsOp.cpp b/src/pathops/SkPathOpsOp.cpp index b71ca9e481..25795047c8 100644 --- a/src/pathops/SkPathOpsOp.cpp +++ b/src/pathops/SkPathOpsOp.cpp @@ -245,8 +245,8 @@ extern void (*gVerboseFinalize)(); #endif -bool OpDebug(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result, - bool expectSuccess SkDEBUGPARAMS(bool skipAssert) SkDEBUGPARAMS(const char* testName)) { +bool OpDebug(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result + SkDEBUGPARAMS(bool skipAssert) SkDEBUGPARAMS(const char* testName)) { SkChunkAlloc allocator(4096); // FIXME: add a constant expression here, tune SkOpContour contour; SkOpContourHead* contourList = static_cast(&contour); @@ -413,7 +413,7 @@ static int debug_paths_draw_the_same(const SkPath& one, const SkPath& two, SkBit bool Op(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result) { #if DEBUG_VERIFY - if (!OpDebug(one, two, op, result, true SkDEBUGPARAMS(nullptr))) { + if (!OpDebug(one, two, op, result SkDEBUGPARAMS(nullptr))) { SkDebugf("%s did not expect failure\none: fill=%d\n", __FUNCTION__, one.getFillType()); one.dumpHex(); SkDebugf("two: fill=%d\n", two.getFillType()); @@ -455,6 +455,6 @@ bool Op(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result) { } return true; #else - return OpDebug(one, two, op, result, true SkDEBUGPARAMS(false) SkDEBUGPARAMS(nullptr)); + return OpDebug(one, two, op, result SkDEBUGPARAMS(false) SkDEBUGPARAMS(nullptr)); #endif } diff --git a/tests/PathOpsExtendedTest.cpp b/tests/PathOpsExtendedTest.cpp index 572766086a..b71b115439 100644 --- a/tests/PathOpsExtendedTest.cpp +++ b/tests/PathOpsExtendedTest.cpp @@ -487,8 +487,8 @@ static void showName(const SkPath& a, const SkPath& b, const SkPathOp shapeOp) { } #endif -bool OpDebug(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result, - bool expectSuccess SkDEBUGPARAMS(bool skipAssert) +bool OpDebug(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result + SkDEBUGPARAMS(bool skipAssert) SkDEBUGPARAMS(const char* testName)); static bool innerPathOp(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b, @@ -497,10 +497,12 @@ static bool innerPathOp(skiatest::Reporter* reporter, const SkPath& a, const SkP showName(a, b, shapeOp); #endif SkPath out; - if (!OpDebug(a, b, shapeOp, &out, expectSuccess SkDEBUGPARAMS(skipAssert) + if (!OpDebug(a, b, shapeOp, &out SkDEBUGPARAMS(skipAssert) SkDEBUGPARAMS(testName))) { - SkDebugf("%s did not expect failure\n", __FUNCTION__); - REPORTER_ASSERT(reporter, 0); + if (expectSuccess) { + SkDebugf("%s did not expect failure\n", __FUNCTION__); + REPORTER_ASSERT(reporter, 0); + } return false; } if (!reporter->verbose()) { @@ -556,6 +558,11 @@ bool testPathSkipAssertOp(skiatest::Reporter* reporter, const SkPath& a, const S return innerPathOp(reporter, a, b, shapeOp, testName, true, true); } +bool testPathFailSkipAssertOp(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b, + const SkPathOp shapeOp, const char* testName) { + return innerPathOp(reporter, a, b, shapeOp, testName, false, true); +} + bool testPathFailOp(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b, const SkPathOp shapeOp, const char* testName) { #if DEBUG_SHOW_TEST_NAME diff --git a/tests/PathOpsExtendedTest.h b/tests/PathOpsExtendedTest.h index 0a6f4ab91f..1fadeb8ca4 100644 --- a/tests/PathOpsExtendedTest.h +++ b/tests/PathOpsExtendedTest.h @@ -44,6 +44,8 @@ extern bool testPathOpFailCheck(skiatest::Reporter* reporter, const SkPath& a, c const SkPathOp , const char* testName); extern bool testPathFailOp(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b, const SkPathOp , const char* testName); +extern bool testPathFailSkipAssertOp(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b, + const SkPathOp , const char* testName); extern bool testPathSkipAssertOp(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b, const SkPathOp , const char* testName); extern bool testSimplify(SkPath& path, bool useXor, SkPath& out, PathOpsThreadState& state, diff --git a/tests/PathOpsOpTest.cpp b/tests/PathOpsOpTest.cpp index d75c9a6fb6..a73bdcf372 100644 --- a/tests/PathOpsOpTest.cpp +++ b/tests/PathOpsOpTest.cpp @@ -5884,7 +5884,70 @@ SkPath path2(path); testPathFailOp(reporter, path1, path2, kUnion_SkPathOp, filename); } +static void fuzz763_9(skiatest::Reporter* reporter, const char* filename) { + SkPath path; + path.setFillType((SkPath::FillType) 1); + + SkPath path1(path); + path.reset(); + path.setFillType((SkPath::FillType) 0); +path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000)); // 0, 0 +path.conicTo(SkBits2Float(0x2a8c555b), SkBits2Float(0x081f2a21), SkBits2Float(0x7bc00321), SkBits2Float(0xed7a6a4b), SkBits2Float(0x1f212a8c)); // 2.49282e-13f, 4.78968e-34f, 1.99397e+36f, -4.84373e+27f, 3.41283e-20f +path.lineTo(SkBits2Float(0x7bc00321), SkBits2Float(0xed7a6a4b)); // 1.99397e+36f, -4.84373e+27f +path.lineTo(SkBits2Float(0x282a3a21), SkBits2Float(0x3a21df28)); // 9.4495e-15f, 0.000617492f +path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000)); // 0, 0 +path.close(); +path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000)); // 0, 0 +path.quadTo(SkBits2Float(0x8a284f9a), SkBits2Float(0x3ac23ab3), SkBits2Float(0x1d2a2928), SkBits2Float(0x63962be6)); // -8.10388e-33f, 0.00148185f, 2.25206e-21f, 5.54035e+21f +path.moveTo(SkBits2Float(0x29272a81), SkBits2Float(0x2ab03a55)); // 3.71183e-14f, 3.13044e-13f +path.quadTo(SkBits2Float(0x2720213b), SkBits2Float(0x3a214729), SkBits2Float(0xdf28282a), SkBits2Float(0x8a2f2121)); // 2.22225e-15f, 0.000615227f, -1.2117e+19f, -8.43217e-33f +path.quadTo(SkBits2Float(0x373b3a27), SkBits2Float(0x201fc4c1), SkBits2Float(0x27576c2a), SkBits2Float(0x5921c25d)); // 1.11596e-05f, 1.35329e-19f, 2.98959e-15f, 2.8457e+15f +path.quadTo(SkBits2Float(0x2720213b), SkBits2Float(0x3a214729), SkBits2Float(0xdf28282a), SkBits2Float(0x3a8a3a21)); // 2.22225e-15f, 0.000615227f, -1.2117e+19f, 0.00105459f +path.cubicTo(SkBits2Float(0x373b3ac5), SkBits2Float(0x201fc422), SkBits2Float(0x523a702a), SkBits2Float(0x27576c51), SkBits2Float(0x5921c25d), SkBits2Float(0x51523a70)); // 1.11598e-05f, 1.35327e-19f, 2.00186e+11f, 2.9896e-15f, 2.8457e+15f, 5.64327e+10f +path.quadTo(SkBits2Float(0xd912102a), SkBits2Float(0x284f9a28), SkBits2Float(0xb38a1f30), SkBits2Float(0x3a3ac23a)); // -2.56957e+15f, 1.15242e-14f, -6.4318e-08f, 0.000712428f +path.lineTo(SkBits2Float(0xc809272a), SkBits2Float(0x29b02829)); // -140445, 7.82294e-14f + + SkPath path2(path); + testPathFailOp(reporter, path1, path2, (SkPathOp) 1, filename); +} + + +static void fuzz763_4(skiatest::Reporter* reporter, const char* filename) { + SkPath path; + path.setFillType((SkPath::FillType) 1); + + SkPath path1(path); + path.reset(); + path.setFillType((SkPath::FillType) 0); +path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000)); // 0, 0 +path.lineTo(SkBits2Float(0x555b3a2d), SkBits2Float(0x2a212a8c)); // 1.50652e+13f, 1.43144e-13f +path.conicTo(SkBits2Float(0xc0032108), SkBits2Float(0x7a6a4b7b), SkBits2Float(0x212a8ced), SkBits2Float(0x0321081f), SkBits2Float(0x6a3a7bc0)); // -2.04889f, 3.04132e+35f, 5.77848e-19f, 4.7323e-37f, 5.63611e+25f +path.conicTo(SkBits2Float(0x3a2147ed), SkBits2Float(0xdf28282a), SkBits2Float(0x3a8a3a21), SkBits2Float(0x8a284f9a), SkBits2Float(0x3ac2b33a)); // 0.000615238f, -1.2117e+19f, 0.00105459f, -8.10388e-33f, 0.00148544f +path.cubicTo(SkBits2Float(0x1d2a2928), SkBits2Float(0x63962be6), SkBits2Float(0x295b2d2a), SkBits2Float(0x68295b2d), SkBits2Float(0x2d296855), SkBits2Float(0x2a8c275b)); // 2.25206e-21f, 5.54035e+21f, 4.86669e-14f, 3.19905e+24f, 9.6297e-12f, 2.48963e-13f +path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000)); // 0, 0 +path.close(); +path.moveTo(SkBits2Float(0x55685b1f), SkBits2Float(0x5b2d2968)); // 1.59674e+13f, 4.87407e+16f +path.lineTo(SkBits2Float(0x2a212a8c), SkBits2Float(0x2a21081f)); // 1.43144e-13f, 1.43025e-13f +path.conicTo(SkBits2Float(0xde6a4b7b), SkBits2Float(0x2a8ced7a), SkBits2Float(0x21081f21), SkBits2Float(0x3a7bc003), SkBits2Float(0x47ed7a6a)); // -4.22068e+18f, 2.50338e-13f, 4.61198e-19f, 0.00096035f, 121589 +path.lineTo(SkBits2Float(0x55685b1f), SkBits2Float(0x5b2d2968)); // 1.59674e+13f, 4.87407e+16f +path.close(); +path.moveTo(SkBits2Float(0x55685b1f), SkBits2Float(0x5b2d2968)); // 1.59674e+13f, 4.87407e+16f +path.quadTo(SkBits2Float(0xdf28282a), SkBits2Float(0x3a8a3a21), SkBits2Float(0x8a284f9a), SkBits2Float(0x3ac23ab3)); // -1.2117e+19f, 0.00105459f, -8.10388e-33f, 0.00148185f +path.lineTo(SkBits2Float(0x2928088c), SkBits2Float(0x2be61d2a)); // 3.73109e-14f, 1.63506e-12f +path.conicTo(SkBits2Float(0x2a812a63), SkBits2Float(0x2d292a27), SkBits2Float(0x5568295b), SkBits2Float(0x5b2d2968), SkBits2Float(0x552d6829)); // 2.29444e-13f, 9.6159e-12f, 1.5954e+13f, 4.87407e+16f, 1.19164e+13f +path.conicTo(SkBits2Float(0x395b2d5b), SkBits2Float(0x68552768), SkBits2Float(0x555b2df0), SkBits2Float(0x1f722a8c), SkBits2Float(0x082a212a)); // 0.000209024f, 4.02636e+24f, 1.50619e+13f, 5.12807e-20f, 5.11965e-34f +path.lineTo(SkBits2Float(0x55685b1f), SkBits2Float(0x5b2d2968)); // 1.59674e+13f, 4.87407e+16f +path.close(); +path.moveTo(SkBits2Float(0x212a8c55), SkBits2Float(0x21081f2a)); // 5.7784e-19f, 4.61198e-19f +path.conicTo(SkBits2Float(0x6a4b7bc0), SkBits2Float(0x2147ed7a), SkBits2Float(0x28282a3a), SkBits2Float(0x21df212a), SkBits2Float(0x033a8a3a)); // 6.14991e+25f, 6.77381e-19f, 9.33503e-15f, 1.51198e-18f, 5.48192e-37f + + SkPath path2(path); + testPathFailSkipAssertOp(reporter, path1, path2, (SkPathOp) 1, filename); +} + static struct TestDesc failTests[] = { + TEST(fuzz763_4), + TEST(fuzz763_9), TEST(fuzz1450_1), TEST(fuzz1450_0), TEST(bug597926_0),