aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/pathops
diff options
context:
space:
mode:
authorGravatar caryclark <caryclark@google.com>2014-09-29 06:58:41 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2014-09-29 06:58:41 -0700
commitc06d9a7a7e7fdd7002e6f7e41e78d90cadfb6094 (patch)
tree9edaa02cfa3d8d99a2a9132a4da5ba8817d59975 /src/pathops
parent05c4a4322e7d4f3417b7df33825bab8603d52051 (diff)
fail on extremely large coincident curves
TBR= BUG=418381 Author: caryclark@google.com Review URL: https://codereview.chromium.org/607913007
Diffstat (limited to 'src/pathops')
-rw-r--r--src/pathops/SkOpSegment.cpp18
-rw-r--r--src/pathops/SkOpSegment.h2
2 files changed, 15 insertions, 5 deletions
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<SkPoint, true>* 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<AlignedSpan>* );
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<SkPoint, true>* outsideTs);
void bumpCoincidentOBlind(int index, int last);
void bumpCoincidentOther(const SkOpSpan& oTest, int* index,