aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/pathops/SkAddIntersections.cpp2
-rw-r--r--src/pathops/SkDConicLineIntersection.cpp11
-rw-r--r--src/pathops/SkIntersections.h8
-rw-r--r--src/pathops/SkOpBuilder.cpp19
-rwxr-xr-xsrc/pathops/SkOpCoincidence.cpp3
-rw-r--r--src/pathops/SkPathOpsCommon.cpp3
-rw-r--r--src/pathops/SkPathOpsCommon.h5
-rw-r--r--src/pathops/SkPathOpsOp.cpp7
-rw-r--r--src/pathops/SkPathOpsSimplify.cpp3
-rw-r--r--src/pathops/SkPathOpsTightBounds.cpp3
-rw-r--r--src/pathops/SkPathOpsTypes.cpp4
-rw-r--r--src/pathops/SkPathOpsTypes.h3
-rwxr-xr-xtests/PathOpsAngleIdeas.cpp2
-rw-r--r--tests/PathOpsAngleTest.cpp4
-rw-r--r--tests/PathOpsBuilderTest.cpp22
-rw-r--r--tests/PathOpsExtendedTest.cpp19
-rw-r--r--tests/PathOpsExtendedTest.h2
-rw-r--r--tests/PathOpsOpTest.cpp50
18 files changed, 141 insertions, 29 deletions
diff --git a/src/pathops/SkAddIntersections.cpp b/src/pathops/SkAddIntersections.cpp
index 43d29d93e0..07666e796d 100644
--- a/src/pathops/SkAddIntersections.cpp
+++ b/src/pathops/SkAddIntersections.cpp
@@ -280,7 +280,7 @@ bool AddIntersectTs(SkOpContour* test, SkOpContour* next, SkOpCoincidence* coinc
continue;
}
int pts = 0;
- SkIntersections ts;
+ SkIntersections ts { SkDEBUGCODE(test->globalState()) };
bool swap = false;
SkDQuad quad1, quad2;
SkDConic conic1, conic2;
diff --git a/src/pathops/SkDConicLineIntersection.cpp b/src/pathops/SkDConicLineIntersection.cpp
index e6d775f76e..2d906072fa 100644
--- a/src/pathops/SkDConicLineIntersection.cpp
+++ b/src/pathops/SkDConicLineIntersection.cpp
@@ -103,9 +103,14 @@ public:
for (int index = 0; index < roots; ++index) {
double conicT = rootVals[index];
double lineT = this->findLineT(conicT);
- SkDEBUGCODE(SkDPoint conicPt = fConic.ptAtT(conicT));
- SkDEBUGCODE(SkDPoint linePt = fLine->ptAtT(lineT));
- SkASSERT(conicPt.approximatelyEqual(linePt));
+#ifdef SK_DEBUG
+ if (!fIntersections->debugGlobalState()
+ || !fIntersections->debugGlobalState()->debugSkipAssert()) {
+ SkDEBUGCODE(SkDPoint conicPt = fConic.ptAtT(conicT));
+ SkDEBUGCODE(SkDPoint linePt = fLine->ptAtT(lineT));
+ SkASSERT(conicPt.approximatelyEqual(linePt));
+ }
+#endif
SkDPoint pt;
if (this->pinTs(&conicT, &lineT, &pt, kPointUninitialized)
&& this->uniqueAnswer(conicT, pt)) {
diff --git a/src/pathops/SkIntersections.h b/src/pathops/SkIntersections.h
index b733ed0ea7..474142b269 100644
--- a/src/pathops/SkIntersections.h
+++ b/src/pathops/SkIntersections.h
@@ -15,9 +15,10 @@
class SkIntersections {
public:
- SkIntersections()
+ SkIntersections(SkDEBUGCODE(SkOpGlobalState* globalState = nullptr))
: fSwap(0)
#ifdef SK_DEBUG
+ SkDEBUGPARAMS(fDebugGlobalState(globalState))
, fDepth(0)
#endif
{
@@ -102,6 +103,10 @@ public:
return intersect(cubic, line);
}
+#ifdef SK_DEBUG
+ SkOpGlobalState* debugGlobalState() { return fDebugGlobalState; }
+#endif
+
bool hasT(double t) const {
SkASSERT(t == 0 || t == 1);
return fUsed > 0 && (t == 0 ? fT[0][0] == 0 : fT[0][fUsed - 1] == 1);
@@ -309,6 +314,7 @@ private:
bool fAllowNear;
bool fSwap;
#ifdef SK_DEBUG
+ SkOpGlobalState* fDebugGlobalState;
int fDepth;
#endif
#if DEBUG_T_SECT_LOOP_COUNT
diff --git a/src/pathops/SkOpBuilder.cpp b/src/pathops/SkOpBuilder.cpp
index 4f53dee056..67aa92fe26 100644
--- a/src/pathops/SkOpBuilder.cpp
+++ b/src/pathops/SkOpBuilder.cpp
@@ -25,7 +25,7 @@ static bool one_contour(const SkPath& path) {
return true;
}
-void FixWinding(SkPath* path) {
+bool FixWinding(SkPath* path) {
SkPath::FillType fillType = path->getFillType();
if (fillType == SkPath::kInverseEvenOdd_FillType) {
fillType = SkPath::kInverseWinding_FillType;
@@ -40,14 +40,17 @@ void FixWinding(SkPath* path) {
*path = temp;
}
path->setFillType(fillType);
- return;
+ return true;
}
SkChunkAlloc allocator(4096);
SkOpContourHead contourHead;
- SkOpGlobalState globalState(nullptr, &contourHead SkDEBUGPARAMS(nullptr));
+ SkOpGlobalState globalState(nullptr, &contourHead SkDEBUGPARAMS(false)
+ SkDEBUGPARAMS(nullptr));
SkOpEdgeBuilder builder(*path, &contourHead, &allocator, &globalState);
builder.finish(&allocator);
- SkASSERT(contourHead.next());
+ if (!contourHead.next()) {
+ return false;
+ }
contourHead.resetReverse();
bool writePath = false;
SkOpSpan* topSpan;
@@ -69,7 +72,7 @@ void FixWinding(SkPath* path) {
}
if (!writePath) {
path->setFillType(fillType);
- return;
+ return true;
}
SkPath empty;
SkPathWriter woundPath(empty);
@@ -83,6 +86,7 @@ void FixWinding(SkPath* path) {
} while ((test = test->next()));
*path = *woundPath.nativePath();
path->setFillType(fillType);
+ return true;
}
void SkOpBuilder::add(const SkPath& path, SkPathOp op) {
@@ -160,7 +164,10 @@ bool SkOpBuilder::resolve(SkPath* result) {
}
if (!fPathRefs[index].isEmpty()) {
// convert the even odd result back to winding form before accumulating it
- FixWinding(&fPathRefs[index]);
+ if (!FixWinding(&fPathRefs[index])) {
+ *result = original;
+ return false;
+ }
sum.addPath(fPathRefs[index]);
}
}
diff --git a/src/pathops/SkOpCoincidence.cpp b/src/pathops/SkOpCoincidence.cpp
index 130d1daff7..42ee5c6091 100755
--- a/src/pathops/SkOpCoincidence.cpp
+++ b/src/pathops/SkOpCoincidence.cpp
@@ -90,6 +90,9 @@ bool SkOpCoincidence::addExpanded(SkChunkAlloc* allocator
}
SkOpSpanBase* test = start->upCast()->next();
SkOpSpanBase* oTest = coin->fFlipped ? oStart->prev() : oStart->upCast()->next();
+ if (!oTest) {
+ return false;
+ }
while (test != end || oTest != oEnd) {
if (!test->ptT()->contains(oTest->ptT())) {
// use t ranges to guess which one is missing
diff --git a/src/pathops/SkPathOpsCommon.cpp b/src/pathops/SkPathOpsCommon.cpp
index c9ef7a4196..340b306d60 100644
--- a/src/pathops/SkPathOpsCommon.cpp
+++ b/src/pathops/SkPathOpsCommon.cpp
@@ -198,7 +198,8 @@ public:
void Assemble(const SkPathWriter& path, SkPathWriter* simple) {
SkChunkAlloc allocator(4096); // FIXME: constant-ize, tune
SkOpContourHead contour;
- SkOpGlobalState globalState(nullptr, &contour SkDEBUGPARAMS(nullptr));
+ SkOpGlobalState globalState(nullptr, &contour SkDEBUGPARAMS(false)
+ SkDEBUGPARAMS(nullptr));
#if DEBUG_SHOW_TEST_NAME
SkDebugf("</div>\n");
#endif
diff --git a/src/pathops/SkPathOpsCommon.h b/src/pathops/SkPathOpsCommon.h
index 73bc0f42cc..856a984ce5 100644
--- a/src/pathops/SkPathOpsCommon.h
+++ b/src/pathops/SkPathOpsCommon.h
@@ -22,11 +22,12 @@ SkOpSegment* FindChase(SkTDArray<SkOpSpanBase*>* chase, SkOpSpanBase** startPtr,
SkOpSpan* FindSortableTop(SkOpContourHead* );
SkOpSegment* FindUndone(SkOpContourHead* , SkOpSpanBase** startPtr,
SkOpSpanBase** endPtr);
-void FixWinding(SkPath* path);
+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(const char* testName));
+ bool expectSuccess SkDEBUGPARAMS(bool skipAssert)
+ SkDEBUGPARAMS(const char* testName));
#if DEBUG_ACTIVE_SPANS
void DebugShowActiveSpans(SkOpContourHead* );
#endif
diff --git a/src/pathops/SkPathOpsOp.cpp b/src/pathops/SkPathOpsOp.cpp
index 257cb8ee69..b71ca9e481 100644
--- a/src/pathops/SkPathOpsOp.cpp
+++ b/src/pathops/SkPathOpsOp.cpp
@@ -246,12 +246,13 @@ extern void (*gVerboseFinalize)();
#endif
bool OpDebug(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result,
- bool expectSuccess SkDEBUGPARAMS(const char* testName)) {
+ bool expectSuccess SkDEBUGPARAMS(bool skipAssert) SkDEBUGPARAMS(const char* testName)) {
SkChunkAlloc allocator(4096); // FIXME: add a constant expression here, tune
SkOpContour contour;
SkOpContourHead* contourList = static_cast<SkOpContourHead*>(&contour);
SkOpCoincidence coincidence;
- SkOpGlobalState globalState(&coincidence, contourList SkDEBUGPARAMS(testName));
+ SkOpGlobalState globalState(&coincidence, contourList
+ SkDEBUGPARAMS(skipAssert) SkDEBUGPARAMS(testName));
#if DEBUGGING_PATHOPS_FROM_HOST
dump_op(one, two, op);
#endif
@@ -454,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(nullptr));
+ return OpDebug(one, two, op, result, true SkDEBUGPARAMS(false) SkDEBUGPARAMS(nullptr));
#endif
}
diff --git a/src/pathops/SkPathOpsSimplify.cpp b/src/pathops/SkPathOpsSimplify.cpp
index 97f0350db2..fa1003054e 100644
--- a/src/pathops/SkPathOpsSimplify.cpp
+++ b/src/pathops/SkPathOpsSimplify.cpp
@@ -180,7 +180,8 @@ bool Simplify(const SkPath& path, SkPath* result) {
SkOpCoincidence coincidence;
SkOpContour contour;
SkOpContourHead* contourList = static_cast<SkOpContourHead*>(&contour);
- SkOpGlobalState globalState(&coincidence, contourList SkDEBUGPARAMS(nullptr));
+ SkOpGlobalState globalState(&coincidence, contourList SkDEBUGPARAMS(false)
+ SkDEBUGPARAMS(nullptr));
#if DEBUG_SORT
SkPathOpsDebug::gSortCount = SkPathOpsDebug::gSortCountDefault;
#endif
diff --git a/src/pathops/SkPathOpsTightBounds.cpp b/src/pathops/SkPathOpsTightBounds.cpp
index ac5d6aae0b..19593c228b 100644
--- a/src/pathops/SkPathOpsTightBounds.cpp
+++ b/src/pathops/SkPathOpsTightBounds.cpp
@@ -11,7 +11,8 @@ bool TightBounds(const SkPath& path, SkRect* result) {
SkChunkAlloc allocator(4096); // FIXME: constant-ize, tune
SkOpContour contour;
SkOpContourHead* contourList = static_cast<SkOpContourHead*>(&contour);
- SkOpGlobalState globalState(nullptr, contourList SkDEBUGPARAMS(nullptr));
+ SkOpGlobalState globalState(nullptr, contourList SkDEBUGPARAMS(false)
+ SkDEBUGPARAMS(nullptr));
// turn path into list of segments
SkOpEdgeBuilder builder(path, &contour, &allocator, &globalState);
if (!builder.finish(&allocator)) {
diff --git a/src/pathops/SkPathOpsTypes.cpp b/src/pathops/SkPathOpsTypes.cpp
index 1ed484afee..bad1bc7a8b 100644
--- a/src/pathops/SkPathOpsTypes.cpp
+++ b/src/pathops/SkPathOpsTypes.cpp
@@ -213,6 +213,7 @@ double SkDCubeRoot(double x) {
}
SkOpGlobalState::SkOpGlobalState(SkOpCoincidence* coincidence, SkOpContourHead* head
+ SkDEBUGPARAMS(bool debugSkipAssert)
SkDEBUGPARAMS(const char* testName))
: fCoincidence(coincidence)
, fContourHead(head)
@@ -226,7 +227,8 @@ SkOpGlobalState::SkOpGlobalState(SkOpCoincidence* coincidence, SkOpContourHead*
SkDEBUGPARAMS(fContourID(0))
SkDEBUGPARAMS(fPtTID(0))
SkDEBUGPARAMS(fSegmentID(0))
- SkDEBUGPARAMS(fSpanID(0)) {
+ SkDEBUGPARAMS(fSpanID(0))
+ SkDEBUGPARAMS(fDebugSkipAssert(debugSkipAssert)) {
if (coincidence) {
coincidence->debugSetGlobalState(this);
}
diff --git a/src/pathops/SkPathOpsTypes.h b/src/pathops/SkPathOpsTypes.h
index b35c97ef06..00c3e5fe93 100644
--- a/src/pathops/SkPathOpsTypes.h
+++ b/src/pathops/SkPathOpsTypes.h
@@ -31,6 +31,7 @@ class SkIntersectionHelper;
class SkOpGlobalState {
public:
SkOpGlobalState(SkOpCoincidence* coincidence, SkOpContourHead* head
+ SkDEBUGPARAMS(bool debugSkipAssert)
SkDEBUGPARAMS(const char* testName));
enum Phase {
@@ -69,6 +70,7 @@ public:
const class SkOpPtT* debugPtT(int id) const;
bool debugRunFail() const;
const class SkOpSegment* debugSegment(int id) const;
+ bool debugSkipAssert() const { return fDebugSkipAssert; }
const class SkOpSpanBase* debugSpan(int id) const;
const char* debugTestName() const { return fDebugTestName; }
#endif
@@ -152,6 +154,7 @@ private:
int fPtTID;
int fSegmentID;
int fSpanID;
+ bool fDebugSkipAssert;
#endif
#if DEBUG_T_SECT_LOOP_COUNT
int fDebugLoopCount[3];
diff --git a/tests/PathOpsAngleIdeas.cpp b/tests/PathOpsAngleIdeas.cpp
index 8fc100ee02..2e3c7b9066 100755
--- a/tests/PathOpsAngleIdeas.cpp
+++ b/tests/PathOpsAngleIdeas.cpp
@@ -419,7 +419,7 @@ static void testQuadAngles(skiatest::Reporter* reporter, const SkDQuad& quad1, c
SkPoint shortQuads[2][3];
SkOpContourHead contour;
- SkOpGlobalState state(nullptr, &contour SkDEBUGPARAMS(nullptr));
+ SkOpGlobalState state(nullptr, &contour SkDEBUGPARAMS(false) SkDEBUGPARAMS(nullptr));
contour.init(&state, false, false);
makeSegment(&contour, quad1, shortQuads[0], allocator);
makeSegment(&contour, quad1, shortQuads[1], allocator);
diff --git a/tests/PathOpsAngleTest.cpp b/tests/PathOpsAngleTest.cpp
index faf5da50f2..6389c305bb 100644
--- a/tests/PathOpsAngleTest.cpp
+++ b/tests/PathOpsAngleTest.cpp
@@ -235,7 +235,7 @@ static const int circleDataSetSize = (int) SK_ARRAY_COUNT(circleDataSet);
DEF_TEST(PathOpsAngleCircle, reporter) {
SkChunkAlloc allocator(4096);
SkOpContourHead contour;
- SkOpGlobalState state(nullptr, &contour SkDEBUGPARAMS(nullptr));
+ SkOpGlobalState state(nullptr, &contour SkDEBUGPARAMS(false) SkDEBUGPARAMS(nullptr));
contour.init(&state, false, false);
for (int index = 0; index < circleDataSetSize; ++index) {
CircleData& data = circleDataSet[index];
@@ -427,7 +427,7 @@ struct FourPoints {
DEF_TEST(PathOpsAngleAfter, reporter) {
SkChunkAlloc allocator(4096);
SkOpContourHead contour;
- SkOpGlobalState state(nullptr, &contour SkDEBUGPARAMS(nullptr));
+ SkOpGlobalState state(nullptr, &contour SkDEBUGPARAMS(false) SkDEBUGPARAMS(nullptr));
contour.init(&state, false, false);
for (int index = intersectDataSetsSize - 1; index >= 0; --index) {
IntersectData* dataArray = intersectDataSets[index];
diff --git a/tests/PathOpsBuilderTest.cpp b/tests/PathOpsBuilderTest.cpp
index e191ecee5e..e29b4bc473 100644
--- a/tests/PathOpsBuilderTest.cpp
+++ b/tests/PathOpsBuilderTest.cpp
@@ -301,3 +301,25 @@ DEF_TEST(Issue569540, reporter) {
SkPath result;
builder.resolve(&result);
}
+
+DEF_TEST(SkOpBuilderFuzz665, reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+path.moveTo(SkBits2Float(0xcc4264a7), SkBits2Float(0x4bb12e50)); // -5.0959e+07f, 2.32235e+07f
+path.lineTo(SkBits2Float(0xcc4264b0), SkBits2Float(0x4bb12e48)); // -5.0959e+07f, 2.32234e+07f
+path.lineTo(SkBits2Float(0xcc4264a7), SkBits2Float(0x4bb12e50)); // -5.0959e+07f, 2.32235e+07f
+path.close();
+ SkPath path1(path);
+ path.reset();
+ path.setFillType(SkPath::kWinding_FillType);
+path.moveTo(SkBits2Float(0x43213333), SkBits2Float(0x43080000)); // 161.2f, 136
+path.lineTo(SkBits2Float(0x43038000), SkBits2Float(0x43080000)); // 131.5f, 136
+path.cubicTo(SkBits2Float(0x43038000), SkBits2Float(0x42f00000), SkBits2Float(0x42f16666), SkBits2Float(0x42d53333), SkBits2Float(0x42d3cccd), SkBits2Float(0x42cd6666)); // 131.5f, 120, 120.7f, 106.6f, 105.9f, 102.7f
+path.lineTo(SkBits2Float(0x42e33333), SkBits2Float(0x42940000)); // 113.6f, 74
+ SkPath path2(path);
+ SkOpBuilder builder;
+ builder.add(path1, kUnion_SkPathOp);
+ builder.add(path2, kUnion_SkPathOp);
+ SkPath result;
+ builder.resolve(&result);
+}
diff --git a/tests/PathOpsExtendedTest.cpp b/tests/PathOpsExtendedTest.cpp
index b5bf5b8d9f..572766086a 100644
--- a/tests/PathOpsExtendedTest.cpp
+++ b/tests/PathOpsExtendedTest.cpp
@@ -488,15 +488,17 @@ 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(const char* testName));
+ bool expectSuccess SkDEBUGPARAMS(bool skipAssert)
+ SkDEBUGPARAMS(const char* testName));
static bool innerPathOp(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b,
- const SkPathOp shapeOp, const char* testName, bool expectSuccess) {
+ const SkPathOp shapeOp, const char* testName, bool expectSuccess, bool skipAssert) {
#if 0 && DEBUG_SHOW_TEST_NAME
showName(a, b, shapeOp);
#endif
SkPath out;
- if (!OpDebug(a, b, shapeOp, &out, expectSuccess SkDEBUGPARAMS(testName))) {
+ if (!OpDebug(a, b, shapeOp, &out, expectSuccess SkDEBUGPARAMS(skipAssert)
+ SkDEBUGPARAMS(testName))) {
SkDebugf("%s did not expect failure\n", __FUNCTION__);
REPORTER_ASSERT(reporter, 0);
return false;
@@ -536,17 +538,22 @@ static bool innerPathOp(skiatest::Reporter* reporter, const SkPath& a, const SkP
bool testPathOp(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b,
const SkPathOp shapeOp, const char* testName) {
- return innerPathOp(reporter, a, b, shapeOp, testName, true);
+ return innerPathOp(reporter, a, b, shapeOp, testName, true, false);
}
bool testPathOpCheck(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b,
const SkPathOp shapeOp, const char* testName, bool checkFail) {
- return innerPathOp(reporter, a, b, shapeOp, testName, checkFail);
+ return innerPathOp(reporter, a, b, shapeOp, testName, checkFail, false);
}
bool testPathOpFailCheck(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b,
const SkPathOp shapeOp, const char* testName) {
- return innerPathOp(reporter, a, b, shapeOp, testName, false);
+ return innerPathOp(reporter, a, b, shapeOp, testName, false, false);
+}
+
+bool testPathSkipAssertOp(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b,
+ const SkPathOp shapeOp, const char* testName) {
+ return innerPathOp(reporter, a, b, shapeOp, testName, true, true);
}
bool testPathFailOp(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b,
diff --git a/tests/PathOpsExtendedTest.h b/tests/PathOpsExtendedTest.h
index 17073833cb..0a6f4ab91f 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 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,
const char* pathStr);
extern bool testSimplify(skiatest::Reporter* reporter, const SkPath& path, const char* filename);
diff --git a/tests/PathOpsOpTest.cpp b/tests/PathOpsOpTest.cpp
index 00a8f52477..d75c9a6fb6 100644
--- a/tests/PathOpsOpTest.cpp
+++ b/tests/PathOpsOpTest.cpp
@@ -5836,7 +5836,57 @@ SkPath path2(path);
testPathFailOp(reporter, path1, path2, (SkPathOp) 1, filename);
}
+static void fuzz1450_0(skiatest::Reporter* reporter, const char* filename) {
+SkPath path;
+path.moveTo(SkBits2Float(0x43b40000), SkBits2Float(0xcf000000)); // 360, -2.14748e+09f
+path.conicTo(SkBits2Float(0x4e800002), SkBits2Float(0xcf000000), SkBits2Float(0x4e800002), SkBits2Float(0xce7ffffe), SkBits2Float(0x3f3504f4)); // 1.07374e+09f, -2.14748e+09f, 1.07374e+09f, -1.07374e+09f, 0.707107f
+path.conicTo(SkBits2Float(0x4e800002), SkBits2Float(0x43800001), SkBits2Float(0x43348000), SkBits2Float(0x43800001), SkBits2Float(0x3f3504f4)); // 1.07374e+09f, 256, 180.5f, 256, 0.707107f
+SkPath path1(path);
+path.reset();
+path.moveTo(SkBits2Float(0x43b40000), SkBits2Float(0x45816000)); // 360, 4140
+path.conicTo(SkBits2Float(0x43b40005), SkBits2Float(0x458a945d), SkBits2Float(0x45610000), SkBits2Float(0x458a945d), SkBits2Float(0x3f3504f3)); // 360, 4434.55f, 3600, 4434.55f, 0.707107f
+path.conicTo(SkBits2Float(0x45d5bfff), SkBits2Float(0x458a945d), SkBits2Float(0x45d5bfff), SkBits2Float(0x45816000), SkBits2Float(0x3f3504f3)); // 6840, 4434.55f, 6840, 4140, 0.707107f
+path.lineTo(SkBits2Float(0x42c80000), SkBits2Float(0x44000000)); // 100, 512
+path.lineTo(SkBits2Float(0x42000000), SkBits2Float(0x41800000)); // 32, 16
+path.lineTo(SkBits2Float(0x43b40000), SkBits2Float(0x44800000)); // 360, 1024
+path.lineTo(SkBits2Float(0x43b40000), SkBits2Float(0x45816000)); // 360, 4140
+path.close();
+SkPath path2(path);
+testPathSkipAssertOp(reporter, path1, path2, kUnion_SkPathOp, filename);
+}
+
+static void fuzz1450_1(skiatest::Reporter* reporter, const char* filename) {
+SkPath path;
+path.setFillType(SkPath::kEvenOdd_FillType);
+path.moveTo(SkBits2Float(0x4e800002), SkBits2Float(0xce7ffffe)); // 1.07374e+09f, -1.07374e+09f
+path.conicTo(SkBits2Float(0x4e800002), SkBits2Float(0xcf000000), SkBits2Float(0x43b40000), SkBits2Float(0xcf000000), SkBits2Float(0x3f3504f4)); // 1.07374e+09f, -2.14748e+09f, 360, -2.14748e+09f, 0.707107f
+path.lineTo(SkBits2Float(0x43348000), SkBits2Float(0x43800001)); // 180.5f, 256
+path.lineTo(SkBits2Float(0x42000000), SkBits2Float(0x41800000)); // 32, 16
+path.lineTo(SkBits2Float(0x42c80000), SkBits2Float(0x44000000)); // 100, 512
+path.lineTo(SkBits2Float(0x43553abd), SkBits2Float(0x440f3cbd)); // 213.229f, 572.949f
+path.lineTo(SkBits2Float(0x43b40000), SkBits2Float(0x44800000)); // 360, 1024
+path.lineTo(SkBits2Float(0x43b40000), SkBits2Float(0x45816000)); // 360, 4140
+path.conicTo(SkBits2Float(0x43b40005), SkBits2Float(0x458a945d), SkBits2Float(0x45610000), SkBits2Float(0x458a945d), SkBits2Float(0x3f3504f3)); // 360, 4434.55f, 3600, 4434.55f, 0.707107f
+path.conicTo(SkBits2Float(0x45d5bfff), SkBits2Float(0x458a945d), SkBits2Float(0x45d5bfff), SkBits2Float(0x45816000), SkBits2Float(0x3f3504f3)); // 6840, 4434.55f, 6840, 4140, 0.707107f
+path.lineTo(SkBits2Float(0x43553abd), SkBits2Float(0x440f3cbd)); // 213.229f, 572.949f
+path.lineTo(SkBits2Float(0x43348000), SkBits2Float(0x43800001)); // 180.5f, 256
+path.conicTo(SkBits2Float(0x4e800002), SkBits2Float(0x43800001), SkBits2Float(0x4e800002), SkBits2Float(0xce7ffffe), SkBits2Float(0x3f3504f4)); // 1.07374e+09f, 256, 1.07374e+09f, -1.07374e+09f, 0.707107f
+path.close();
+SkPath path1(path);
+path.reset();
+path.moveTo(SkBits2Float(0x42fe0000), SkBits2Float(0x43a08000)); // 127, 321
+path.lineTo(SkBits2Float(0x45d5c000), SkBits2Float(0x43870000)); // 6840, 270
+path.lineTo(SkBits2Float(0xd0a00000), SkBits2Float(0x4cbebc20)); // -2.14748e+10f, 1e+08
+path.lineTo(SkBits2Float(0x451f7000), SkBits2Float(0x42800000)); // 2551, 64
+path.lineTo(SkBits2Float(0x42fe0000), SkBits2Float(0x43a08000)); // 127, 321
+path.close();
+SkPath path2(path);
+testPathFailOp(reporter, path1, path2, kUnion_SkPathOp, filename);
+}
+
static struct TestDesc failTests[] = {
+ TEST(fuzz1450_1),
+ TEST(fuzz1450_0),
TEST(bug597926_0),
TEST(fuzz535151),
TEST(fuzz753_91),