aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Cary Clark <caryclark@skia.org>2018-03-19 09:42:00 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-03-19 14:06:25 +0000
commit0949beeaf440bc0022703951741f8a6abf379d88 (patch)
tree7464e828b4e1b56b8544773c199997cdeff41785
parent8d2ba44c9cba790cfd8ace80de9e15972bccbe5d (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.cpp4
-rw-r--r--src/pathops/SkPathOpsTSect.h34
-rw-r--r--tests/PathOpsTestCommon.cpp5
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;