diff options
author | Cary Clark <caryclark@skia.org> | 2018-03-19 09:42:00 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-03-19 14:06:25 +0000 |
commit | 0949beeaf440bc0022703951741f8a6abf379d88 (patch) | |
tree | 7464e828b4e1b56b8544773c199997cdeff41785 | |
parent | 8d2ba44c9cba790cfd8ace80de9e15972bccbe5d (diff) |
fix op fuzz
fixes the current four fuzzer fails by rewriting
asserts as function exits. Passes all extended
pathops testing.
To run the extended tests:
./out/debug/pathops_unittest -V -x
./out/release/pathops_unittest -V -x
R=kjlubick@google.com
Docs-Preview: https://skia.org/?cl=114962
Bug: skia:
Change-Id: I05bd368a87b38b1121403cf93b21caf76c2e7d7e
Reviewed-on: https://skia-review.googlesource.com/114962
Commit-Queue: Cary Clark <caryclark@skia.org>
Reviewed-by: Kevin Lubick <kjlubick@google.com>
-rw-r--r-- | src/pathops/SkOpCoincidence.cpp | 4 | ||||
-rw-r--r-- | src/pathops/SkPathOpsTSect.h | 34 | ||||
-rw-r--r-- | tests/PathOpsTestCommon.cpp | 5 |
3 files changed, 27 insertions, 16 deletions
diff --git a/src/pathops/SkOpCoincidence.cpp b/src/pathops/SkOpCoincidence.cpp index 3251ec4371..da1e18eb2c 100644 --- a/src/pathops/SkOpCoincidence.cpp +++ b/src/pathops/SkOpCoincidence.cpp @@ -693,7 +693,7 @@ bool SkOpCoincidence::addOrOverlap(SkOpSegment* coinSeg, SkOpSegment* oppSeg, } FAIL_IF(cs && cs->deleted()); FAIL_IF(os && os->deleted()); - SkASSERT(!ce || !ce->deleted()); + FAIL_IF(ce && ce->deleted()); FAIL_IF(oe && oe->deleted()); const SkOpPtT* csExisting = !cs ? coinSeg->existing(coinTs, nullptr) : nullptr; const SkOpPtT* ceExisting = !ce ? coinSeg->existing(coinTe, nullptr) : nullptr; @@ -1095,7 +1095,7 @@ bool SkOpCoincidence::apply(DEBUG_COIN_DECLARE_ONLY_PARAMS()) { SkDebugf("seg=%d span=%d windValue=%d oppValue=%d\n", oSegment->debugID(), oStart->debugID(), oWindValue, oOppValue); #endif - FAIL_IF(windValue == -1); + FAIL_IF(windValue <= -1); start->setWindValue(windValue); start->setOppValue(oppValue); FAIL_IF(oWindValue <= -1); diff --git a/src/pathops/SkPathOpsTSect.h b/src/pathops/SkPathOpsTSect.h index 1e78f2a108..4dc2b34bb7 100644 --- a/src/pathops/SkPathOpsTSect.h +++ b/src/pathops/SkPathOpsTSect.h @@ -19,6 +19,10 @@ typedef uint8_t SkOpDebugBool; typedef bool SkOpDebugBool; #endif +static inline bool SkDoubleIsNaN(double x) { + return x != x; +} + /* TCurve and OppCurve are one of { SkDQuadratic, SkDConic, SkDCubic } */ template<typename TCurve, typename OppCurve> class SkTCoincident { @@ -233,8 +237,7 @@ public: SkIntersections* intersections); SkDEBUGCODE(SkOpGlobalState* globalState() { return fDebugGlobalState; }) - // for testing only - bool debugHasBounded(const SkTSpan<OppCurve, TCurve>* ) const; + bool hasBounded(const SkTSpan<OppCurve, TCurve>* ) const; const SkTSect<OppCurve, TCurve>* debugOpp() const { return SkDEBUGRELEASE(fOppSect, nullptr); @@ -307,14 +310,14 @@ private: bool* calcMatched, bool* oppMatched) const; void mergeCoincidence(SkTSect<OppCurve, TCurve>* sect2); SkTSpan<TCurve, OppCurve>* prev(SkTSpan<TCurve, OppCurve>* ) const; - void removeByPerpendicular(SkTSect<OppCurve, TCurve>* opp); + bool removeByPerpendicular(SkTSect<OppCurve, TCurve>* opp); void recoverCollapsed(); bool removeCoincident(SkTSpan<TCurve, OppCurve>* span, bool isBetween); void removeAllBut(const SkTSpan<OppCurve, TCurve>* keep, SkTSpan<TCurve, OppCurve>* span, SkTSect<OppCurve, TCurve>* opp); bool removeSpan(SkTSpan<TCurve, OppCurve>* span); void removeSpanRange(SkTSpan<TCurve, OppCurve>* first, SkTSpan<TCurve, OppCurve>* last); - void removeSpans(SkTSpan<TCurve, OppCurve>* span, SkTSect<OppCurve, TCurve>* opp); + bool removeSpans(SkTSpan<TCurve, OppCurve>* span, SkTSect<OppCurve, TCurve>* opp); void removedEndCheck(SkTSpan<TCurve, OppCurve>* span); void resetRemovedEnds() { @@ -572,6 +575,9 @@ void SkTSpan<TCurve, OppCurve>::init(const TCurve& c) { template<typename TCurve, typename OppCurve> bool SkTSpan<TCurve, OppCurve>::initBounds(const TCurve& c) { + if (SkDoubleIsNaN(fStartT) || SkDoubleIsNaN(fEndT)) { + return false; + } fPart = c.subDivide(fStartT, fEndT); fBounds.setBounds(fPart); fCoinStart.init(); @@ -1147,7 +1153,7 @@ int SkTSect<TCurve, OppCurve>::countConsecutiveSpans(SkTSpan<TCurve, OppCurve>* } template<typename TCurve, typename OppCurve> -bool SkTSect<TCurve, OppCurve>::debugHasBounded(const SkTSpan<OppCurve, TCurve>* span) const { +bool SkTSect<TCurve, OppCurve>::hasBounded(const SkTSpan<OppCurve, TCurve>* span) const { const SkTSpan<TCurve, OppCurve>* test = fHead; if (!test) { return false; @@ -1725,7 +1731,7 @@ void SkTSect<TCurve, OppCurve>::removeAllBut(const SkTSpan<OppCurve, TCurve>* ke } template<typename TCurve, typename OppCurve> -void SkTSect<TCurve, OppCurve>::removeByPerpendicular(SkTSect<OppCurve, TCurve>* opp) { +bool SkTSect<TCurve, OppCurve>::removeByPerpendicular(SkTSect<OppCurve, TCurve>* opp) { SkTSpan<TCurve, OppCurve>* test = fHead; SkTSpan<TCurve, OppCurve>* next; do { @@ -1742,8 +1748,11 @@ void SkTSect<TCurve, OppCurve>::removeByPerpendicular(SkTSect<OppCurve, TCurve>* if (startV.dot(endV) <= 0) { continue; } - this->removeSpans(test, opp); + if (!this->removeSpans(test, opp)) { + return false; + } } while ((test = next)); + return true; } template<typename TCurve, typename OppCurve> @@ -1803,7 +1812,7 @@ void SkTSect<TCurve, OppCurve>::removeSpanRange(SkTSpan<TCurve, OppCurve>* first } template<typename TCurve, typename OppCurve> -void SkTSect<TCurve, OppCurve>::removeSpans(SkTSpan<TCurve, OppCurve>* span, +bool SkTSect<TCurve, OppCurve>::removeSpans(SkTSpan<TCurve, OppCurve>* span, SkTSect<OppCurve, TCurve>* opp) { SkTSpanBounded<OppCurve, TCurve>* bounded = span->fBounded; while (bounded) { @@ -1815,9 +1824,12 @@ void SkTSect<TCurve, OppCurve>::removeSpans(SkTSpan<TCurve, OppCurve>* span, if (spanBounded->removeBounded(span)) { opp->removeSpan(spanBounded); } - SkASSERT(!span->fDeleted || !opp->debugHasBounded(span)); + if (span->fDeleted && opp->hasBounded(span)) { + return false; + } bounded = next; } + return true; } template<typename TCurve, typename OppCurve> @@ -2265,7 +2277,9 @@ void SkTSect<TCurve, OppCurve>::BinarySearch(SkTSect<TCurve, OppCurve>* sect1, return; } sect2->computePerpendiculars(sect1, sect2->fHead, sect2->tail()); - sect1->removeByPerpendicular(sect2); + if (!sect1->removeByPerpendicular(sect2)) { + return; + } sect1->validate(); sect2->validate(); #if DEBUG_T_SECT_LOOP_COUNT diff --git a/tests/PathOpsTestCommon.cpp b/tests/PathOpsTestCommon.cpp index 8cc8fe879d..d7db579d9c 100644 --- a/tests/PathOpsTestCommon.cpp +++ b/tests/PathOpsTestCommon.cpp @@ -10,6 +10,7 @@ #include "SkPathOpsCubic.h" #include "SkPathOpsLine.h" #include "SkPathOpsQuad.h" +#include "SkPathOpsTSect.h" #include "SkReduceOrder.h" #include "SkTSort.h" @@ -248,10 +249,6 @@ void CubicPathToSimple(const SkPath& cubicPath, SkPath* simplePath) { } } -static bool SkDoubleIsNaN(double x) { - return x != x; -} - bool ValidBounds(const SkPathOpsBounds& bounds) { if (SkScalarIsNaN(bounds.fLeft)) { return false; |