aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rwxr-xr-xsrc/pathops/SkOpCoincidence.cpp12
-rw-r--r--src/pathops/SkOpCoincidence.h2
-rwxr-xr-xsrc/pathops/SkOpSpan.cpp4
-rw-r--r--src/pathops/SkPathOpsCommon.cpp4
-rw-r--r--src/pathops/SkPathOpsDebug.cpp25
-rw-r--r--tests/PathOpsOpTest.cpp114
6 files changed, 130 insertions, 31 deletions
diff --git a/src/pathops/SkOpCoincidence.cpp b/src/pathops/SkOpCoincidence.cpp
index 8734cb0d92..aa5f5bfba7 100755
--- a/src/pathops/SkOpCoincidence.cpp
+++ b/src/pathops/SkOpCoincidence.cpp
@@ -1262,14 +1262,16 @@ void SkOpCoincidence::fixUp(SkCoincidentSpans* coin, SkOpPtT* deleted, const SkO
// Please keep this in sync with debugMark()
/* this sets up the coincidence links in the segments when the coincidence crosses multiple spans */
-void SkOpCoincidence::mark(DEBUG_COIN_DECLARE_ONLY_PARAMS()) {
+bool SkOpCoincidence::mark(DEBUG_COIN_DECLARE_ONLY_PARAMS()) {
DEBUG_SET_PHASE();
SkCoincidentSpans* coin = fHead;
if (!coin) {
- return;
+ return true;
}
do {
- SkOpSpan* start = coin->coinPtTStartWritable()->span()->upCast();
+ SkOpSpanBase* startBase = coin->coinPtTStartWritable()->span();
+ FAIL_IF(!startBase->upCastable());
+ SkOpSpan* start = startBase->upCast();
SkASSERT(!start->deleted());
SkOpSpanBase* end = coin->coinPtTEndWritable()->span();
SkOPASSERT(!end->deleted());
@@ -1291,12 +1293,14 @@ void SkOpCoincidence::mark(DEBUG_COIN_DECLARE_ONLY_PARAMS()) {
SkOpSpanBase* oNext = oStart;
bool ordered = coin->ordered();
while ((next = next->upCast()->next()) != end) {
+ FAIL_IF(!next->upCastable());
SkAssertResult(next->upCast()->insertCoincidence(oSegment, flipped, ordered));
}
while ((oNext = oNext->upCast()->next()) != oEnd) {
- SkAssertResult(oNext->upCast()->insertCoincidence(segment, flipped, ordered));
+ FAIL_IF(!oNext->upCast()->insertCoincidence(segment, flipped, ordered));
}
} while ((coin = coin->next()));
+ return true;
}
// Please keep in sync with debugMarkCollapsed()
diff --git a/src/pathops/SkOpCoincidence.h b/src/pathops/SkOpCoincidence.h
index 3f8816e45c..e2188bebbd 100644
--- a/src/pathops/SkOpCoincidence.h
+++ b/src/pathops/SkOpCoincidence.h
@@ -227,7 +227,7 @@ public:
return !fHead && !fTop;
}
- void mark(DEBUG_COIN_DECLARE_ONLY_PARAMS());
+ bool mark(DEBUG_COIN_DECLARE_ONLY_PARAMS());
void markCollapsed(SkOpPtT* );
static bool Ordered(const SkOpPtT* coinPtTStart, const SkOpPtT* oppPtTStart) {
diff --git a/src/pathops/SkOpSpan.cpp b/src/pathops/SkOpSpan.cpp
index 2abc44e248..40d6383c74 100755
--- a/src/pathops/SkOpSpan.cpp
+++ b/src/pathops/SkOpSpan.cpp
@@ -407,7 +407,9 @@ bool SkOpSpan::insertCoincidence(const SkOpSegment* segment, bool flipped, bool
SkOpSpan* span;
SkOpSpanBase* base = next->span();
if (!ordered) {
- const SkOpSpanBase* spanEnd = fNext->contains(segment)->span();
+ const SkOpPtT* spanEndPtT = fNext->contains(segment);
+ FAIL_IF(!spanEndPtT);
+ const SkOpSpanBase* spanEnd = spanEndPtT->span();
const SkOpPtT* start = base->ptT()->starter(spanEnd->ptT());
FAIL_IF(!start->span()->upCastable());
span = const_cast<SkOpSpan*>(start->span()->upCast());
diff --git a/src/pathops/SkPathOpsCommon.cpp b/src/pathops/SkPathOpsCommon.cpp
index b0a24a7094..b4049bc5d9 100644
--- a/src/pathops/SkPathOpsCommon.cpp
+++ b/src/pathops/SkPathOpsCommon.cpp
@@ -302,7 +302,9 @@ bool HandleCoincidence(SkOpContourHead* contourList, SkOpCoincidence* coincidenc
if (!coincidence->addExpanded(DEBUG_COIN_ONLY_PARAMS())) {
return false;
}
- coincidence->mark(DEBUG_PHASE_ONLY_PARAMS(kWalking));
+ if (!coincidence->mark(DEBUG_PHASE_ONLY_PARAMS(kWalking))) {
+ return false;
+ }
} else {
(void) coincidence->expand(DEBUG_COIN_ONLY_PARAMS());
}
diff --git a/src/pathops/SkPathOpsDebug.cpp b/src/pathops/SkPathOpsDebug.cpp
index e744c75658..a0fcff58e0 100644
--- a/src/pathops/SkPathOpsDebug.cpp
+++ b/src/pathops/SkPathOpsDebug.cpp
@@ -277,7 +277,7 @@ static void move_nearby(SkPathOpsDebug::GlitchLog* glitches, const SkOpContourHe
void SkOpGlobalState::debugAddToCoinChangedDict() {
#if DEBUG_COINCIDENCE
- CheckHealth(contourList);
+ SkPathOpsDebug::CheckHealth(fContourHead);
#endif
// see if next coincident operation makes a change; if so, record it
SkPathOpsDebug::GlitchLog glitches;
@@ -477,14 +477,6 @@ void SkPathOpsDebug::MathematicaIze(char* str, size_t bufferLen) {
}
}
-#if DEBUG_VALIDATE
-void SkPathOpsDebug::SetPhase(SkOpContourHead* contourList, CoinID next,
- int lineNumber, SkOpPhase phase) {
- AddedCoin(contourList, next, 0, lineNumber);
- contourList->globalState()->setPhase(phase);
-}
-#endif
-
bool SkPathOpsDebug::ValidWind(int wind) {
return wind > SK_MinS32 + 0xFFFF && wind < SK_MaxS32 - 0xFFFF;
}
@@ -1688,21 +1680,6 @@ void SkOpCoincidence::debugAddExpanded(SkPathOpsDebug::GlitchLog* log) const {
return;
}
-/* Commented-out lines keep this in sync with addIfMissing() */
-void SkOpCoincidence::debugAddIfMissing(SkPathOpsDebug::GlitchLog* log, const SkCoincidentSpans* outer, const SkOpPtT* over1s,
- const SkOpPtT* over1e) const {
-// SkASSERT(fTop);
- if (fTop && alreadyAdded(fTop, outer, over1s, over1e)) { // in debug, fTop may be null
- return;
- }
- if (fHead && alreadyAdded(fHead, outer, over1s, over1e)) {
- return;
- }
- log->record(SkPathOpsDebug::kAddIfMissingCoin_Glitch, outer->coinPtTStart(), outer->coinPtTEnd(), over1s, over1e);
- this->debugValidate();
- return;
-}
-
/* Commented-out lines keep this in sync addIfMissing() */
// note that over1s, over1e, over2s, over2e are ordered
void SkOpCoincidence::debugAddIfMissing(SkPathOpsDebug::GlitchLog* log, const SkOpPtT* over1s, const SkOpPtT* over2s,
diff --git a/tests/PathOpsOpTest.cpp b/tests/PathOpsOpTest.cpp
index b5cbb9d32d..84f2310f96 100644
--- a/tests/PathOpsOpTest.cpp
+++ b/tests/PathOpsOpTest.cpp
@@ -8185,7 +8185,121 @@ path.close();
testPathOpFuzz(reporter, path1, path2, (SkPathOp) 0, filename);
}
+// hangs 654939
+static void fuzz763_54(skiatest::Reporter* reporter, const char* filename) {
+ SkPath path;
+ path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000)); // 0, 0
+path.conicTo(SkBits2Float(0x5b682968), SkBits2Float(0xb3b32d11), SkBits2Float(0xb3b3b3b3), SkBits2Float(0x5b29b3b3), SkBits2Float(0x212a8c55)); // 6.53477e+16f, -8.34353e-08f, -8.36802e-08f, 4.77669e+16f, 5.7784e-19f
+path.conicTo(SkBits2Float(0x68555b2d), SkBits2Float(0x28296869), SkBits2Float(0x5b252a08), SkBits2Float(0x5d68392a), SkBits2Float(0x29282780)); // 4.03018e+24f, 9.40402e-15f, 4.64896e+16f, 1.04584e+18f, 3.73378e-14f
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000)); // 0, 0
+path.close();
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000)); // 0, 0
+path.cubicTo(SkBits2Float(0x52727272), SkBits2Float(0x72727252), SkBits2Float(0x525252c7), SkBits2Float(0x72725252), SkBits2Float(0x72727272), SkBits2Float(0x72727255)); // 2.60326e+11f, 4.80215e+30f, 2.25833e+11f, 4.79967e+30f, 4.80216e+30f, 4.80215e+30f
+path.quadTo(SkBits2Float(0xd7da0000), SkBits2Float(0x5252525a), SkBits2Float(0x72525252), SkBits2Float(0x72727272)); // -4.79387e+14f, 2.25831e+11f, 4.16585e+30f, 4.80216e+30f
+path.quadTo(SkBits2Float(0x48525252), SkBits2Float(0x72725252), SkBits2Float(0x72727272), SkBits2Float(0x72727255)); // 215369, 4.79967e+30f, 4.80216e+30f, 4.80215e+30f
+path.quadTo(SkBits2Float(0xdada007b), SkBits2Float(0x5252525a), SkBits2Float(0x72675252), SkBits2Float(0x72727272)); // -3.0681e+16f, 2.25831e+11f, 4.5818e+30f, 4.80216e+30f
+path.quadTo(SkBits2Float(0x52525252), SkBits2Float(0x27725252), SkBits2Float(0x72727272), SkBits2Float(0x72727272)); // 2.25831e+11f, 3.36289e-15f, 4.80216e+30f, 4.80216e+30f
+path.quadTo(SkBits2Float(0x1c292172), SkBits2Float(0x7bc00321), SkBits2Float(0x9aaaaaaa), SkBits2Float(0x8c556a4b)); // 5.59606e-22f, 1.99397e+36f, -7.05861e-23f, -1.64409e-31f
+path.quadTo(SkBits2Float(0x72725572), SkBits2Float(0x00007272), SkBits2Float(0x525adada), SkBits2Float(0x52525252)); // 4.79991e+30f, 4.10552e-41f, 2.34994e+11f, 2.25831e+11f
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000)); // 0, 0
+path.close();
+path.moveTo(SkBits2Float(0xa5252600), SkBits2Float(0x52b4adad)); // -1.43243e-16f, 3.88004e+11f
+path.close();
+path.moveTo(SkBits2Float(0xa5252600), SkBits2Float(0x52b4adad)); // -1.43243e-16f, 3.88004e+11f
+path.quadTo(SkBits2Float(0x72725570), SkBits2Float(0x52525272), SkBits2Float(0x72525252), SkBits2Float(0x72727272)); // 4.79991e+30f, 2.25832e+11f, 4.16585e+30f, 4.80216e+30f
+path.quadTo(SkBits2Float(0x72727255), SkBits2Float(0x555bb672), SkBits2Float(0x29686968), SkBits2Float(0x252a081f)); // 4.80215e+30f, 1.50985e+13f, 5.16058e-14f, 1.47479e-16f
+path.moveTo(SkBits2Float(0x5d68392a), SkBits2Float(0x01002780)); // 1.04584e+18f, 2.35382e-38f
+path.moveTo(SkBits2Float(0x72727200), SkBits2Float(0x72725252)); // 4.80212e+30f, 4.79967e+30f
+path.quadTo(SkBits2Float(0x5adada00), SkBits2Float(0xa5252652), SkBits2Float(0x727272ad), SkBits2Float(0xda007b72)); // 3.08006e+16f, -1.43245e-16f, 4.80218e+30f, -9.04113e+15f
+path.lineTo(SkBits2Float(0x5252525a), SkBits2Float(0x72525252)); // 2.25831e+11f, 4.16585e+30f
+path.quadTo(SkBits2Float(0x72727272), SkBits2Float(0x52525252), SkBits2Float(0x27725252), SkBits2Float(0x72727272)); // 4.80216e+30f, 2.25831e+11f, 3.36289e-15f, 4.80216e+30f
+path.quadTo(SkBits2Float(0x72727272), SkBits2Float(0x74217472), SkBits2Float(0x005b5574), SkBits2Float(0x72680000)); // 4.80216e+30f, 5.11671e+31f, 8.38768e-39f, 4.59523e+30f
+path.quadTo(SkBits2Float(0x72727272), SkBits2Float(0x52525252), SkBits2Float(0x007b7272), SkBits2Float(0x525adada)); // 4.80216e+30f, 2.25831e+11f, 1.13368e-38f, 2.34994e+11f
+path.lineTo(SkBits2Float(0x72727200), SkBits2Float(0x72725252)); // 4.80212e+30f, 4.79967e+30f
+path.close();
+
+ SkPath path1(path);
+ path.reset();
+ path.setFillType((SkPath::FillType) 0);
+
+ SkPath path2(path);
+ testPathOpFuzz(reporter, path1, path2, (SkPathOp) 4, filename);
+}
+
+
+// afl crash
+static void fuzz763_55(skiatest::Reporter* reporter, const char* filename) {
+ SkPath path;
+ path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0x55415500)); // 0, 1.32857e+13f
+path.lineTo(SkBits2Float(0x55555568), SkBits2Float(0x55555555)); // 1.46602e+13f, 1.46602e+13f
+path.lineTo(SkBits2Float(0x98989898), SkBits2Float(0x55989898)); // -3.94452e-24f, 2.09726e+13f
+path.lineTo(SkBits2Float(0xf6f65555), SkBits2Float(0x101006f6)); // -2.49812e+33f, 2.84044e-29f
+path.quadTo(SkBits2Float(0xdca33f10), SkBits2Float(0xf6f6f6f6), SkBits2Float(0xf621f6f6), SkBits2Float(0xf70ff6f6)); // -3.67598e+17f, -2.50452e+33f, -8.21259e+32f, -2.91995e+33f
+path.lineTo(SkBits2Float(0x9400f6f6), SkBits2Float(0x10530000)); // -6.51105e-27f, 4.16124e-29f
+path.quadTo(SkBits2Float(0x0f101010), SkBits2Float(0x00101010), SkBits2Float(0xf610f720), SkBits2Float(0xf6f6f6f6)); // 7.10284e-30f, 1.47513e-39f, -7.35062e+32f, -2.50452e+33f
+path.lineTo(SkBits2Float(0x105352f6), SkBits2Float(0x1cf6ff10)); // 4.16763e-29f, 1.63448e-21f
+path.lineTo(SkBits2Float(0xf6f6220a), SkBits2Float(0x003700f6)); // -2.49608e+33f, 5.0513e-39f
+path.cubicTo(SkBits2Float(0x0000001e), SkBits2Float(0x00fff4f6), SkBits2Float(0xff101064), SkBits2Float(0xf6b6ac7f), SkBits2Float(0xf6f629f6), SkBits2Float(0x10f6f6f6)); // 4.2039e-44f, 2.35059e-38f, -1.91494e+38f, -1.85253e+33f, -2.4964e+33f, 9.74104e-29f
+path.quadTo(SkBits2Float(0x10101007), SkBits2Float(0x10f7fd10), SkBits2Float(0xf6f6f6f6), SkBits2Float(0xf6f645e0)); // 2.84113e-29f, 9.78142e-29f, -2.50452e+33f, -2.4975e+33f
+path.lineTo(SkBits2Float(0xed9ef6f6), SkBits2Float(0x53535353)); // -6.14965e+27f, 9.07636e+11f
+path.lineTo(SkBits2Float(0x53006cf6), SkBits2Float(0x53295353)); // 5.51584e+11f, 7.27247e+11f
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0x55415500)); // 0, 1.32857e+13f
+path.close();
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0x55415500)); // 0, 1.32857e+13f
+path.lineTo(SkBits2Float(0xf6f6f6f6), SkBits2Float(0x5353d9f6)); // -2.50452e+33f, 9.09895e+11f
+
+ SkPath path1(path);
+ path.reset();
+ path.setFillType((SkPath::FillType) 0);
+
+ SkPath path2(path);
+ testPathOpFuzz(reporter, path1, path2, (SkPathOp) 3, filename);
+}
+
+// 656149
+static void fuzz763_56(skiatest::Reporter* reporter, const char* filename) {
+ SkPath path;
+ path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000)); // 0, 0
+path.conicTo(SkBits2Float(0x5b682968), SkBits2Float(0xb3b32d11), SkBits2Float(0xb3b3b3b3), SkBits2Float(0x5b29b3b3), SkBits2Float(0x72725255)); // 6.53477e+16f, -8.34353e-08f, -8.36802e-08f, 4.77669e+16f, 4.79967e+30f
+path.quadTo(SkBits2Float(0x525252c7), SkBits2Float(0x72725252), SkBits2Float(0x72727272), SkBits2Float(0x72727255)); // 2.25833e+11f, 4.79967e+30f, 4.80216e+30f, 4.80215e+30f
+path.quadTo(SkBits2Float(0xd7da0000), SkBits2Float(0x5adada00), SkBits2Float(0x52525252), SkBits2Float(0x00005252)); // -4.79387e+14f, 3.08006e+16f, 2.25831e+11f, 2.9531e-41f
+path.conicTo(SkBits2Float(0xadada525), SkBits2Float(0x52525ab4), SkBits2Float(0x52525252), SkBits2Float(0x72727272), SkBits2Float(0x52527272)); // -1.97412e-11f, 2.25866e+11f, 2.25831e+11f, 4.80216e+30f, 2.25966e+11f
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000)); // 0, 0
+path.close();
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000)); // 0, 0
+path.quadTo(SkBits2Float(0x72725252), SkBits2Float(0x72727272), SkBits2Float(0x72727255), SkBits2Float(0xda007b72)); // 4.79967e+30f, 4.80216e+30f, 4.80215e+30f, -9.04113e+15f
+path.lineTo(SkBits2Float(0x5252525a), SkBits2Float(0x72525252)); // 2.25831e+11f, 4.16585e+30f
+path.quadTo(SkBits2Float(0x72727272), SkBits2Float(0x52525252), SkBits2Float(0x27725252), SkBits2Float(0x72727272)); // 4.80216e+30f, 2.25831e+11f, 3.36289e-15f, 4.80216e+30f
+path.lineTo(SkBits2Float(0x7bc00321), SkBits2Float(0x9aaaaaaa)); // 1.99397e+36f, -7.05861e-23f
+path.quadTo(SkBits2Float(0x72725572), SkBits2Float(0x00007272), SkBits2Float(0x525adada), SkBits2Float(0x52525252)); // 4.79991e+30f, 4.10552e-41f, 2.34994e+11f, 2.25831e+11f
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000)); // 0, 0
+path.close();
+path.moveTo(SkBits2Float(0xa5252600), SkBits2Float(0x52b4adad)); // -1.43243e-16f, 3.88004e+11f
+path.close();
+path.moveTo(SkBits2Float(0xa5252600), SkBits2Float(0x52b4adad)); // -1.43243e-16f, 3.88004e+11f
+path.quadTo(SkBits2Float(0x72727270), SkBits2Float(0x52525272), SkBits2Float(0x72525252), SkBits2Float(0x72727272)); // 4.80216e+30f, 2.25832e+11f, 4.16585e+30f, 4.80216e+30f
+path.quadTo(SkBits2Float(0x72727255), SkBits2Float(0xda007b72), SkBits2Float(0x26525ada), SkBits2Float(0x72ada525)); // 4.80215e+30f, -9.04113e+15f, 7.29815e-16f, 6.87879e+30f
+path.quadTo(SkBits2Float(0x007b7272), SkBits2Float(0x525adada), SkBits2Float(0x52525252), SkBits2Float(0x72727252)); // 1.13368e-38f, 2.34994e+11f, 2.25831e+11f, 4.80215e+30f
+path.quadTo(SkBits2Float(0x52527272), SkBits2Float(0x52525252), SkBits2Float(0x72722772), SkBits2Float(0x72727272)); // 2.25966e+11f, 2.25831e+11f, 4.79636e+30f, 4.80216e+30f
+path.quadTo(SkBits2Float(0x74727272), SkBits2Float(0x55747421), SkBits2Float(0x0000005b), SkBits2Float(0x72727268)); // 7.68345e+31f, 1.67987e+13f, 1.27518e-43f, 4.80216e+30f
+path.quadTo(SkBits2Float(0x52527272), SkBits2Float(0x52525252), SkBits2Float(0x72727272), SkBits2Float(0x72557272)); // 2.25966e+11f, 2.25831e+11f, 4.80216e+30f, 4.22775e+30f
+path.quadTo(SkBits2Float(0x5adada72), SkBits2Float(0x52525252), SkBits2Float(0x72725252), SkBits2Float(0x72727272)); // 3.08009e+16f, 2.25831e+11f, 4.79967e+30f, 4.80216e+30f
+
+ SkPath path1(path);
+ path.reset();
+ path.setFillType((SkPath::FillType) 0);
+
+ SkPath path2(path);
+ testPathOpFuzz(reporter, path1, path2, (SkPathOp) 0, filename);
+}
+
static struct TestDesc failTests[] = {
+ TEST(fuzz763_56),
+ TEST(fuzz763_55),
+ TEST(fuzz763_54),
TEST(fuzz763_53),
TEST(fuzz763_52),
TEST(fuzz763_51),