diff options
author | caryclark <caryclark@google.com> | 2015-07-23 12:40:22 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-07-23 12:40:22 -0700 |
commit | d4349723fac9c0fd4dcf8c275fb7c756bdfdff7b (patch) | |
tree | 20a850a4c02da163ac18a888494813fccc6f1862 | |
parent | a0170f10aadca337fc412953f3409eb368c6964b (diff) |
fix path ops fuzz buster
Mark collapsed segments as done and remove collapsed
segment references from the coincidence array.
Also add test names to global debugging.
R=fmalita@chromium.org
BUG=512592
Review URL: https://codereview.chromium.org/1250293002
-rw-r--r-- | src/pathops/SkOpBuilder.cpp | 2 | ||||
-rwxr-xr-x | src/pathops/SkOpCoincidence.cpp | 10 | ||||
-rw-r--r-- | src/pathops/SkOpContour.h | 9 | ||||
-rw-r--r-- | src/pathops/SkOpSegment.cpp | 9 | ||||
-rw-r--r-- | src/pathops/SkOpSegment.h | 1 | ||||
-rwxr-xr-x | src/pathops/SkOpSpan.cpp | 10 | ||||
-rw-r--r-- | src/pathops/SkOpSpan.h | 5 | ||||
-rw-r--r-- | src/pathops/SkPathOpsCommon.cpp | 10 | ||||
-rw-r--r-- | src/pathops/SkPathOpsCommon.h | 3 | ||||
-rw-r--r-- | src/pathops/SkPathOpsOp.cpp | 6 | ||||
-rw-r--r-- | src/pathops/SkPathOpsSimplify.cpp | 2 | ||||
-rw-r--r-- | src/pathops/SkPathOpsTightBounds.cpp | 2 | ||||
-rw-r--r-- | src/pathops/SkPathOpsTypes.cpp | 4 | ||||
-rw-r--r-- | src/pathops/SkPathOpsTypes.h | 5 | ||||
-rwxr-xr-x | tests/PathOpsAngleIdeas.cpp | 2 | ||||
-rw-r--r-- | tests/PathOpsAngleTest.cpp | 4 | ||||
-rw-r--r-- | tests/PathOpsBuilderTest.cpp | 121 | ||||
-rw-r--r-- | tests/PathOpsExtendedTest.cpp | 5 | ||||
-rw-r--r-- | tests/PathOpsSimplifyTest.cpp | 65 |
19 files changed, 260 insertions, 15 deletions
diff --git a/src/pathops/SkOpBuilder.cpp b/src/pathops/SkOpBuilder.cpp index 0d229a8c40..24a157afc5 100644 --- a/src/pathops/SkOpBuilder.cpp +++ b/src/pathops/SkOpBuilder.cpp @@ -44,7 +44,7 @@ void FixWinding(SkPath* path) { } SkChunkAlloc allocator(4096); SkOpContourHead contourHead; - SkOpGlobalState globalState(NULL, &contourHead); + SkOpGlobalState globalState(NULL, &contourHead SkDEBUGPARAMS(NULL)); SkOpEdgeBuilder builder(*path, &contourHead, &allocator, &globalState); builder.finish(&allocator); SkASSERT(contourHead.next()); diff --git a/src/pathops/SkOpCoincidence.cpp b/src/pathops/SkOpCoincidence.cpp index 58ff7f3ab9..46d06e9e0b 100755 --- a/src/pathops/SkOpCoincidence.cpp +++ b/src/pathops/SkOpCoincidence.cpp @@ -568,6 +568,16 @@ void SkOpCoincidence::fixAligned() { coin->fOppPtTEnd = coin->fOppPtTEnd->doppelganger(); } } while ((coin = coin->fNext)); + coin = fHead; + SkCoincidentSpans** priorPtr = &fHead; + do { + if (coin->fCoinPtTStart->collapsed(coin->fCoinPtTEnd) + || coin->fOppPtTStart->collapsed(coin->fOppPtTEnd)) { + *priorPtr = coin->fNext; + continue; + } + priorPtr = &coin->fNext; + } while ((coin = coin->fNext)); } void SkOpCoincidence::fixUp(SkOpPtT* deleted, SkOpPtT* kept) { diff --git a/src/pathops/SkOpContour.h b/src/pathops/SkOpContour.h index 1225416eaa..7ef68b0377 100644 --- a/src/pathops/SkOpContour.h +++ b/src/pathops/SkOpContour.h @@ -192,6 +192,15 @@ public: return fTail->pts()[SkPathOpsVerbToPoints(fTail->verb())]; } + bool findCollapsed() { + SkASSERT(fCount > 0); + SkOpSegment* segment = &fHead; + do { + segment->findCollapsed(); + } while ((segment = segment->next())); + return true; + } + SkOpSpan* findSortableTop(SkOpContour* ); SkOpSegment* first() { diff --git a/src/pathops/SkOpSegment.cpp b/src/pathops/SkOpSegment.cpp index fd8ab65acd..fc32643558 100644 --- a/src/pathops/SkOpSegment.cpp +++ b/src/pathops/SkOpSegment.cpp @@ -615,6 +615,15 @@ double SkOpSegment::distSq(double t, SkOpAngle* oppAngle) { return closestDistSq; } +void SkOpSegment::findCollapsed() { + if (fHead.contains(&fTail)) { + markAllDone(); + // move start and end to the same point + fHead.alignEnd(0, fHead.pt()); + fTail.setAligned(); + } +} + /* The M and S variable name parts stand for the operators. Mi stands for Minuend (see wiki subtraction, analogous to difference) diff --git a/src/pathops/SkOpSegment.h b/src/pathops/SkOpSegment.h index 6873203b25..a3f5989824 100644 --- a/src/pathops/SkOpSegment.h +++ b/src/pathops/SkOpSegment.h @@ -182,6 +182,7 @@ public: void dumpPts() const; void dumpPtsInner() const; + void findCollapsed(); SkOpSegment* findNextOp(SkTDArray<SkOpSpanBase*>* chase, SkOpSpanBase** nextStart, SkOpSpanBase** nextEnd, bool* unsortable, SkPathOp op, int xorMiMask, int xorSuMask); diff --git a/src/pathops/SkOpSpan.cpp b/src/pathops/SkOpSpan.cpp index f5a52099da..5c89c736fb 100755 --- a/src/pathops/SkOpSpan.cpp +++ b/src/pathops/SkOpSpan.cpp @@ -13,6 +13,16 @@ bool SkOpPtT::alias() const { return this->span()->ptT() != this; } +bool SkOpPtT::collapsed(const SkOpPtT* check) const { + if (fPt != check->fPt) { + return false; + } + SkASSERT(this != check); + const SkOpSegment* segment = this->segment(); + SkASSERT(segment == check->segment()); + return segment->collapsed(); +} + bool SkOpPtT::contains(const SkOpPtT* check) const { SkASSERT(this != check); const SkOpPtT* ptT = this; diff --git a/src/pathops/SkOpSpan.h b/src/pathops/SkOpSpan.h index ec62246c31..2a11c96dd7 100644 --- a/src/pathops/SkOpSpan.h +++ b/src/pathops/SkOpSpan.h @@ -48,6 +48,7 @@ public: } bool alias() const; + bool collapsed(const SkOpPtT* ) const; bool contains(const SkOpPtT* ) const; SkOpPtT* contains(const SkOpSegment* ); SkOpContour* contour() const; @@ -266,6 +267,10 @@ public: return fSegment; } + void setAligned() { + fAligned = true; + } + void setChased(bool chased) { fChased = chased; } diff --git a/src/pathops/SkPathOpsCommon.cpp b/src/pathops/SkPathOpsCommon.cpp index 4ead297f7d..c53f458d1a 100644 --- a/src/pathops/SkPathOpsCommon.cpp +++ b/src/pathops/SkPathOpsCommon.cpp @@ -198,7 +198,7 @@ public: void Assemble(const SkPathWriter& path, SkPathWriter* simple) { SkChunkAlloc allocator(4096); // FIXME: constant-ize, tune SkOpContourHead contour; - SkOpGlobalState globalState(NULL, &contour); + SkOpGlobalState globalState(NULL, &contour SkDEBUGPARAMS(NULL)); #if DEBUG_SHOW_TEST_NAME SkDebugf("</div>\n"); #endif @@ -408,6 +408,13 @@ static void calcAngles(SkOpContourHead* contourList, SkChunkAlloc* allocator) { } while ((contour = contour->next())); } +static void findCollapsed(SkOpContourHead* contourList) { + SkOpContour* contour = contourList; + do { + contour->findCollapsed(); + } while ((contour = contour->next())); +} + static bool missingCoincidence(SkOpContourHead* contourList, SkOpCoincidence* coincidence, SkChunkAlloc* allocator) { SkOpContour* contour = contourList; @@ -444,6 +451,7 @@ bool HandleCoincidence(SkOpContourHead* contourList, SkOpCoincidence* coincidenc SkOpGlobalState* globalState = contourList->globalState(); // combine t values when multiple intersections occur on some segments but not others moveMultiples(contourList); + findCollapsed(contourList); // move t values and points together to eliminate small/tiny gaps moveNearby(contourList); align(contourList); // give all span members common values diff --git a/src/pathops/SkPathOpsCommon.h b/src/pathops/SkPathOpsCommon.h index f76d57c83b..73bc0f42cc 100644 --- a/src/pathops/SkPathOpsCommon.h +++ b/src/pathops/SkPathOpsCommon.h @@ -25,7 +25,8 @@ SkOpSegment* FindUndone(SkOpContourHead* , SkOpSpanBase** startPtr, void 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); +bool OpDebug(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result, + bool expectSuccess 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 9c09eaf8f3..12a9578dd3 100644 --- a/src/pathops/SkPathOpsOp.cpp +++ b/src/pathops/SkPathOpsOp.cpp @@ -223,12 +223,12 @@ static void dump_op(const SkPath& one, const SkPath& two, SkPathOp op) { #endif bool OpDebug(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result, - bool expectSuccess) { + bool expectSuccess 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); + SkOpGlobalState globalState(&coincidence, contourList SkDEBUGPARAMS(testName)); #if DEBUGGING_PATHOPS_FROM_HOST dump_op(one, two, op); #endif @@ -304,5 +304,5 @@ bool OpDebug(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result, } bool Op(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result) { - return OpDebug(one, two, op, result, true); + return OpDebug(one, two, op, result, true SkDEBUGPARAMS(NULL)); } diff --git a/src/pathops/SkPathOpsSimplify.cpp b/src/pathops/SkPathOpsSimplify.cpp index 11b6833a73..8c07653320 100644 --- a/src/pathops/SkPathOpsSimplify.cpp +++ b/src/pathops/SkPathOpsSimplify.cpp @@ -167,7 +167,7 @@ bool Simplify(const SkPath& path, SkPath* result) { SkOpCoincidence coincidence; SkOpContour contour; SkOpContourHead* contourList = static_cast<SkOpContourHead*>(&contour); - SkOpGlobalState globalState(&coincidence, contourList); + SkOpGlobalState globalState(&coincidence, contourList SkDEBUGPARAMS(NULL)); #if DEBUG_SORT SkPathOpsDebug::gSortCount = SkPathOpsDebug::gSortCountDefault; #endif diff --git a/src/pathops/SkPathOpsTightBounds.cpp b/src/pathops/SkPathOpsTightBounds.cpp index f60c291710..7eb72a9037 100644 --- a/src/pathops/SkPathOpsTightBounds.cpp +++ b/src/pathops/SkPathOpsTightBounds.cpp @@ -11,7 +11,7 @@ bool TightBounds(const SkPath& path, SkRect* result) { SkChunkAlloc allocator(4096); // FIXME: constant-ize, tune SkOpContour contour; SkOpContourHead* contourList = static_cast<SkOpContourHead*>(&contour); - SkOpGlobalState globalState(NULL, contourList); + SkOpGlobalState globalState(NULL, contourList SkDEBUGPARAMS(NULL)); // 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 dcd33c9d73..c3de93a94a 100644 --- a/src/pathops/SkPathOpsTypes.cpp +++ b/src/pathops/SkPathOpsTypes.cpp @@ -200,13 +200,15 @@ double SkDCubeRoot(double x) { return result; } -SkOpGlobalState::SkOpGlobalState(SkOpCoincidence* coincidence, SkOpContourHead* head) +SkOpGlobalState::SkOpGlobalState(SkOpCoincidence* coincidence, SkOpContourHead* head + SkDEBUGPARAMS(const char* testName)) : fCoincidence(coincidence) , fContourHead(head) , fNested(0) , fWindingFailed(false) , fAngleCoincidence(false) , fPhase(kIntersecting) + SkDEBUGPARAMS(fDebugTestName(testName)) SkDEBUGPARAMS(fAngleID(0)) SkDEBUGPARAMS(fContourID(0)) SkDEBUGPARAMS(fPtTID(0)) diff --git a/src/pathops/SkPathOpsTypes.h b/src/pathops/SkPathOpsTypes.h index 9550aa1ead..2cd45a5c4d 100644 --- a/src/pathops/SkPathOpsTypes.h +++ b/src/pathops/SkPathOpsTypes.h @@ -28,7 +28,8 @@ class SkOpContourHead; class SkOpGlobalState { public: - SkOpGlobalState(SkOpCoincidence* coincidence, SkOpContourHead* head); + SkOpGlobalState(SkOpCoincidence* coincidence, SkOpContourHead* head + SkDEBUGPARAMS(const char* testName)); enum Phase { kIntersecting, @@ -67,6 +68,7 @@ public: bool debugRunFail() const; const class SkOpSegment* debugSegment(int id) const; const class SkOpSpanBase* debugSpan(int id) const; + const char* debugTestName() const { return fDebugTestName; } #endif int nested() const { @@ -128,6 +130,7 @@ private: bool fAngleCoincidence; Phase fPhase; #ifdef SK_DEBUG + const char* fDebugTestName; int fAngleID; int fContourID; int fPtTID; diff --git a/tests/PathOpsAngleIdeas.cpp b/tests/PathOpsAngleIdeas.cpp index 79e09b9865..88b469e21a 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(NULL, &contour); + SkOpGlobalState state(NULL, &contour SkDEBUGPARAMS(NULL)); 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 9c707743cf..9f9c321a42 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(NULL, &contour); + SkOpGlobalState state(NULL, &contour SkDEBUGPARAMS(NULL)); 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(NULL, &contour); + SkOpGlobalState state(NULL, &contour SkDEBUGPARAMS(NULL)); 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 df77100b01..08fc632732 100644 --- a/tests/PathOpsBuilderTest.cpp +++ b/tests/PathOpsBuilderTest.cpp @@ -150,3 +150,124 @@ DEF_TEST(BuilderIssue502792_2, reporter) { SkPath result; builder.resolve(&result); } + +DEF_TEST(Fuzz846, reporter) { +/* +<clipPath id="clip-circle"> + <circle id="circle" cx="60" cy="60" r="50" /> +</clipPath> +<clipPath id="clip-rect"> + <clipPath id="clip-rect"> + <clipPath id="clip-rect"> + <clipPath id="clip-rect"> + <rect x="10" y="30" width="0" height="60" /> + <rect x="10" y="30" width="0" height="60" /> + <rect x="10" y="30" width="100" height="60" /> + <rect x="10" y="30" width="32668" /> + <rect x="10" y="30" width="100" height="18446744073709551615" /> + <rect x="10" y="255" width="100" height="60" /> + <rect width="100" height="60" /> + <rect x="10" y="30" width="100" height="60" /> + <rect x="10" y="30" width="100" height="4294967236" /> + <rect x="10" y="30" width="100" height="60" /> + </clipPath> + <rect x="10" y="30" width="0" height="60" /> + <rect x="10" y="30" width="0" height="0.18093252719929986369568203" /> + <rect x="10" y="30" width="100" height="60" /> + <rect x="10" y="30" width="32668" height="60" /> + <rect x="10" y="30" width="100" height="18446744073709551615" /> + <rect x="10" y="255" width="100" height="60" /> + <rect x="2147483649" y="30" width="100" height="60" /> + <rect x="10" y="30" width="100" height="60" /> + <rect x="10" y="30" width="100" height="60" /> + <rect x="10" y="30" width="100" height="60" /> + </clipPath> + <rect x="10" y="30" width="0" height="60" /> + <rect x="10" y="30" width="0" height="60" /> + <rect x="10" y="30" width="100" height="60" /> + <rect x="10" y="30" width="32668" height="60" /> + <rect x="10" y="30" width="100" height="18446744073709551615" /> + <rect x="10" y="255" width="100" height="60" /> + <rect x="2147483649" y="30" width="100" height="60" /> + <rect x="10" y="30" width="100" height="60" /> + <rect x="10" y="2879753595" width="100" height="60" /> + <rect x="10" y="30" width="100" height="60" /> + </clipPath> + <rect x="10" y="30" width="100" height="60" /> + <rect x="10" y="30" width="0" height="60" /> + <rect x="10" y="30" width="100" height="60" /> + <rect x="10" y="30" width="32668" height="60" /> + <rect x="10" y="30" width="100" height="18446744073709551615" /> + <rect x="10" y="255" width="100" height="60" /> + <rect x="2147483649" y="30" width="100" height="60" /> + <rect x="10" y="30" width="100" height="60" /> + <rect x="10" y="30" width="100" height="4294967236" /> + <rect x="10" y="30" width="100" height="4294967236" /> + <rect x="10" y="30" width="100" height="4294967236" /> + <rect x="10" y="30" width="100" height="4294967236" /> + <rect x="10" y="30" width="100" height="60" /> + <rect x="757798030" y="30" width="100" height="60" /> +*/ + SkPath clipCircle, clipRect; + SkPath inner; + clipCircle.addCircle(60, 60, 50); // <circle id="circle" cx="60" cy="60" r="50" /> + + inner.addRect(10, 30, 10+0, 30+60); // <rect x="10" y="30" width="0" height="60" /> + inner.addRect(10, 30, 10+0, 30+60); // <rect x="10" y="30" width="0" height="60" /> + inner.addRect(10, 30, 10+100, 30+60); // <rect x="10" y="30" width="100" height="60" /> + inner.addRect(10, 30, 10+32668, 30+0); // <rect x="10" y="30" width="32668" /> + inner.addRect(10, 30, 10+100, 30+18446744073709551615.f); // <rect x="10" y="30" width="100" height="18446744073709551615" /> + inner.addRect(10, 255, 10+100, 255+60); // <rect x="10" y="255" width="100" height="60" /> + inner.addRect(0, 0, 0+100, 0+60); // <rect width="100" height="60" /> + inner.addRect(10, 30, 10+100, 30+60); // <rect x="10" y="30" width="100" height="60" /> + inner.addRect(10, 30, 10+100, 30+4294967236.f); // <rect x="10" y="30" width="100" height="4294967236" /> + inner.addRect(10, 30, 10+100, 30+60); // <rect x="10" y="30" width="100" height="60" /> + clipRect.addPath(inner); + inner.reset(); + inner.addRect(10, 30, 10+0, 30+60); // <rect x="10" y="30" width="0" height="60" /> + inner.addRect(10, 30, 10+0, 30+0.18093252719929986369568203f); // <rect x="10" y="30" width="0" height="0.18093252719929986369568203" /> + inner.addRect(10, 30, 10+100, 30+60); // <rect x="10" y="30" width="100" height="60" /> + inner.addRect(10, 30, 10+32668, 30+60); // <rect x="10" y="30" width="32668" height="60" /> + inner.addRect(10, 30, 10+100, 30+18446744073709551615.f); // <rect x="10" y="30" width="100" height="18446744073709551615" /> + inner.addRect(10, 255, 10+100, 255+60); // <rect x="10" y="255" width="100" height="60" /> + inner.addRect(2147483649.f, 30, 2147483649.f+100, 30+60); // <rect x="2147483649" y="30" width="100" height="60" /> + inner.addRect(10, 30, 10+100, 30+60); // <rect x="10" y="30" width="100" height="60" /> + inner.addRect(10, 30, 10+100, 30+60); // <rect x="10" y="30" width="100" height="60" /> + inner.addRect(10, 30, 10+100, 30+60); // <rect x="10" y="30" width="100" height="60" /> + clipRect.addPath(inner); + inner.reset(); + inner.addRect(10, 30, 10+0, 30+60); // <rect x="10" y="30" width="0" height="60" /> + inner.addRect(10, 30, 10+0, 30+60); // <rect x="10" y="30" width="0" height="60" /> + inner.addRect(10, 30, 10+100, 30+60); // <rect x="10" y="30" width="100" height="60" /> + inner.addRect(10, 30, 10+32668, 30+60); // <rect x="10" y="30" width="32668" height="60" /> + inner.addRect(10, 30, 10+100, 30+18446744073709551615.f); // <rect x="10" y="30" width="100" height="18446744073709551615" /> + inner.addRect(10, 255, 10+100, 255+60); // <rect x="10" y="255" width="100" height="60" /> + inner.addRect(2147483649.f, 30, 2147483649.f+100, 30+60); // <rect x="2147483649" y="30" width="100" height="60" /> + inner.addRect(10, 30, 10+100, 30+60); // <rect x="10" y="30" width="100" height="60" /> + inner.addRect(10, 2879753595.f, 10+100, 30+2879753595.f); // <rect x="10" y="2879753595" width="100" height="60" /> + inner.addRect(10, 30, 10+100, 30+60); // <rect x="10" y="30" width="100" height="60" /> + clipRect.addPath(inner); + inner.reset(); + inner.addRect(10, 30, 10+100, 30+60); // <rect x="10" y="30" width="100" height="60" /> + inner.addRect(10, 30, 10+0, 30+60); // <rect x="10" y="30" width="0" height="60" /> + inner.addRect(10, 30, 10+100, 30+60); // <rect x="10" y="30" width="100" height="60" /> + inner.addRect(10, 30, 10+32668, 30+60); // <rect x="10" y="30" width="32668" height="60" /> + inner.addRect(10, 30, 10+100, 30+18446744073709551615.f); // <rect x="10" y="30" width="100" height="18446744073709551615" /> + inner.addRect(10, 255, 10+100, 255+60); // <rect x="10" y="255" width="100" height="60" /> + inner.addRect(2147483649.f, 30, 2147483649.f+100, 30+60); // <rect x="2147483649" y="30" width="100" height="60" /> + inner.addRect(10, 30, 10+100, 30+60); // <rect x="10" y="30" width="100" height="60" /> + inner.addRect(10, 30, 10+100, 30+4294967236.f); // <rect x="10" y="30" width="100" height="4294967236" /> + inner.addRect(10, 30, 10+100, 30+4294967236.f); // <rect x="10" y="30" width="100" height="4294967236" /> + inner.addRect(10, 30, 10+100, 30+4294967236.f); // <rect x="10" y="30" width="100" height="4294967236" /> + inner.addRect(10, 30, 10+100, 30+4294967236.f); // <rect x="10" y="30" width="100" height="4294967236" /> + inner.addRect(10, 30, 10+100, 30+60); // <rect x="10" y="30" width="100" height="60" /> + inner.addRect(757798030.f, 30, 757798030.f+100, 30+60); // <rect x="757798030" y="30" width="100" height="60" /> + clipRect.addPath(inner); + + SkOpBuilder builder; + builder.add(clipCircle, kUnion_SkPathOp); + builder.add(clipRect, kDifference_SkPathOp); + SkPath result; + builder.resolve(&result); +} + diff --git a/tests/PathOpsExtendedTest.cpp b/tests/PathOpsExtendedTest.cpp index 69a2d617b0..d458c41e97 100644 --- a/tests/PathOpsExtendedTest.cpp +++ b/tests/PathOpsExtendedTest.cpp @@ -488,7 +488,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); +bool OpDebug(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result, + bool expectSuccess SkDEBUGPARAMS(const char* testName)); static bool innerPathOp(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b, const SkPathOp shapeOp, const char* testName, bool expectSuccess) { @@ -496,7 +497,7 @@ 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)) { + if (!OpDebug(a, b, shapeOp, &out, expectSuccess SkDEBUGPARAMS(testName))) { SkDebugf("%s did not expect failure\n", __FUNCTION__); REPORTER_ASSERT(reporter, 0); return false; diff --git a/tests/PathOpsSimplifyTest.cpp b/tests/PathOpsSimplifyTest.cpp index 5b763dee83..165ee8d11d 100644 --- a/tests/PathOpsSimplifyTest.cpp +++ b/tests/PathOpsSimplifyTest.cpp @@ -4810,11 +4810,76 @@ static void testQuads65(skiatest::Reporter* reporter,const char* filename) { testSimplify(reporter, path, filename); } +static void fuzz864a(skiatest::Reporter* reporter,const char* filename) { + SkPath path; + path.moveTo(10, 90); + path.lineTo(10, 90); + path.lineTo(10, 30); + path.lineTo(10, 30); + path.lineTo(10, 90); + path.close(); + path.moveTo(10, 90); + path.lineTo(10, 90); + path.lineTo(10, 30); + path.lineTo(10, 30); + path.lineTo(10, 90); + path.close(); + path.moveTo(10, 90); + path.lineTo(110, 90); + path.lineTo(110, 30); + path.lineTo(10, 30); + path.lineTo(10, 90); + path.close(); + path.moveTo(10, 30); + path.lineTo(32678, 30); + path.lineTo(32678, 30); + path.lineTo(10, 30); + path.close(); + path.moveTo(10, 3.35545e+07f); + path.lineTo(110, 3.35545e+07f); + path.lineTo(110, 30); + path.lineTo(10, 30); + path.lineTo(10, 3.35545e+07f); + path.close(); + path.moveTo(10, 315); + path.lineTo(110, 315); + path.lineTo(110, 255); + path.lineTo(10, 255); + path.lineTo(10, 315); + path.close(); + path.moveTo(0, 60); + path.lineTo(100, 60); + path.lineTo(100, 0); + path.lineTo(0, 0); + path.lineTo(0, 60); + path.close(); + path.moveTo(10, 90); + path.lineTo(110, 90); + path.lineTo(110, 30); + path.lineTo(10, 30); + path.lineTo(10, 90); + path.close(); + path.moveTo(10, 3.35545e+07f); + path.lineTo(110, 3.35545e+07f); + path.lineTo(110, 30); + path.lineTo(10, 30); + path.lineTo(10, 3.35545e+07f); + path.close(); + path.moveTo(10, 90); + path.lineTo(110, 90); + path.lineTo(110, 30); + path.lineTo(10, 30); + path.lineTo(10, 90); + path.close(); + testSimplify(reporter, path, filename); +} + static void (*skipTest)(skiatest::Reporter* , const char* filename) = 0; static void (*firstTest)(skiatest::Reporter* , const char* filename) = 0; static void (*stopTest)(skiatest::Reporter* , const char* filename) = 0; static TestDesc tests[] = { + TEST(fuzz864a), TEST(testQuads65), TEST(testIssue3838_3), TEST(testIssue3838), |