diff options
-rwxr-xr-x | src/pathops/SkOpCoincidence.cpp | 12 | ||||
-rw-r--r-- | src/pathops/SkOpCoincidence.h | 2 | ||||
-rwxr-xr-x | src/pathops/SkOpSpan.cpp | 4 | ||||
-rw-r--r-- | src/pathops/SkPathOpsCommon.cpp | 4 | ||||
-rw-r--r-- | src/pathops/SkPathOpsDebug.cpp | 25 | ||||
-rw-r--r-- | tests/PathOpsOpTest.cpp | 114 |
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), |