From c06d9a7a7e7fdd7002e6f7e41e78d90cadfb6094 Mon Sep 17 00:00:00 2001 From: caryclark Date: Mon, 29 Sep 2014 06:58:41 -0700 Subject: fail on extremely large coincident curves TBR= BUG=418381 Author: caryclark@google.com Review URL: https://codereview.chromium.org/607913007 --- src/pathops/SkOpSegment.cpp | 18 ++++++++++++++---- src/pathops/SkOpSegment.h | 2 +- 2 files changed, 15 insertions(+), 5 deletions(-) (limited to 'src/pathops') diff --git a/src/pathops/SkOpSegment.cpp b/src/pathops/SkOpSegment.cpp index 2dda11a383..95046e2fd2 100644 --- a/src/pathops/SkOpSegment.cpp +++ b/src/pathops/SkOpSegment.cpp @@ -1211,7 +1211,7 @@ void SkOpSegment::bumpCoincidentBlind(bool binary, int index, int endIndex) { } while (++index < endIndex); } -void SkOpSegment::bumpCoincidentThis(const SkOpSpan& oTest, bool binary, int* indexPtr, +bool SkOpSegment::bumpCoincidentThis(const SkOpSpan& oTest, bool binary, int* indexPtr, SkTArray* outsideTs) { int index = *indexPtr; int oWindValue = oTest.fWindValue; @@ -1223,12 +1223,16 @@ void SkOpSegment::bumpCoincidentThis(const SkOpSpan& oTest, bool binary, int* in SkOpSpan* end = test; const SkPoint& oStartPt = oTest.fPt; do { + if (end->fDone && !end->fTiny && !end->fSmall) { // extremely large paths trigger this + return false; + } if (bumpSpan(end, oWindValue, oOppValue)) { TrackOutside(outsideTs, oStartPt); } end = &fTs[++index]; } while ((end->fPt == test->fPt || precisely_equal(end->fT, test->fT)) && end->fT < 1); *indexPtr = index; + return true; } void SkOpSegment::bumpCoincidentOBlind(int index, int endIndex) { @@ -1329,10 +1333,14 @@ bool SkOpSegment::addTCoincident(const SkPoint& startPt, const SkPoint& endPt, d } while (*oTestPt == other->fTs[oIndex].fPt); } else { if (!binary || test->fWindValue + oTest->fOppValue >= 0) { - bumpCoincidentThis(*oTest, binary, &index, &outsidePts); + if (!bumpCoincidentThis(*oTest, binary, &index, &outsidePts)) { + return false; + } other->bumpCoincidentOther(*test, &oIndex, &oOutsidePts); } else { - other->bumpCoincidentThis(*test, binary, &oIndex, &oOutsidePts); + if (!other->bumpCoincidentThis(*test, binary, &oIndex, &oOutsidePts)) { + return false; + } bumpCoincidentOther(*oTest, &index, &outsidePts); } } @@ -1396,7 +1404,9 @@ bool SkOpSegment::addTCoincident(const SkPoint& startPt, const SkPoint& endPt, d if (!binary || test->fWindValue + oTest->fOppValue >= 0) { other->bumpCoincidentOther(*test, &oIndex, &oOutsidePts); } else { - other->bumpCoincidentThis(*test, binary, &oIndex, &oOutsidePts); + if (!other->bumpCoincidentThis(*test, binary, &oIndex, &oOutsidePts)) { + return false; + } } oTest = &other->fTs[oIndex]; oTestPt = &oTest->fPt; diff --git a/src/pathops/SkOpSegment.h b/src/pathops/SkOpSegment.h index 24d08bd814..4c35ac7e7e 100644 --- a/src/pathops/SkOpSegment.h +++ b/src/pathops/SkOpSegment.h @@ -407,7 +407,7 @@ private: const SkOpSegment* other2, SkOpSpan* oSpan, SkTDArray* ); bool betweenPoints(double midT, const SkPoint& pt1, const SkPoint& pt2) const; void bumpCoincidentBlind(bool binary, int index, int last); - void bumpCoincidentThis(const SkOpSpan& oTest, bool binary, int* index, + bool bumpCoincidentThis(const SkOpSpan& oTest, bool binary, int* index, SkTArray* outsideTs); void bumpCoincidentOBlind(int index, int last); void bumpCoincidentOther(const SkOpSpan& oTest, int* index, -- cgit v1.2.3