diff options
author | caryclark <caryclark@google.com> | 2016-06-28 09:23:57 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-06-28 09:23:57 -0700 |
commit | 3f0753d3eccece8ac7f02f6af36d66a96c3dfb26 (patch) | |
tree | a7dca73764a07182471f1c69de159d92059ee9bf /src/pathops/SkOpCoincidence.cpp | |
parent | 74139f1b49d02b38006170c3e50439c1b33b175f (diff) |
fix fuzz bugs
Detect more places where the pathops numerics cause numbers
to become nearly identical and subsequently fail. These tests
have extreme inputs and cannot succeed.
Also remove the expectSuccess parameter from PathOpsDebug
and check instead in the test framework.
R=mbarbella@chromium.org
TBR=reed@google.com
BUG=623072,623022
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2103513002
Review-Url: https://codereview.chromium.org/2103513002
Diffstat (limited to 'src/pathops/SkOpCoincidence.cpp')
-rwxr-xr-x | src/pathops/SkOpCoincidence.cpp | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/src/pathops/SkOpCoincidence.cpp b/src/pathops/SkOpCoincidence.cpp index b72bd6cb37..4b46e685ee 100755 --- a/src/pathops/SkOpCoincidence.cpp +++ b/src/pathops/SkOpCoincidence.cpp @@ -326,34 +326,41 @@ bool SkOpCoincidence::addMissing(SkChunkAlloc* allocator) { return added; } -void SkOpCoincidence::addOverlap(SkOpSegment* seg1, SkOpSegment* seg1o, SkOpSegment* seg2, +bool SkOpCoincidence::addOverlap(SkOpSegment* seg1, SkOpSegment* seg1o, SkOpSegment* seg2, SkOpSegment* seg2o, SkOpPtT* overS, SkOpPtT* overE, SkChunkAlloc* allocator) { SkOpPtT* s1 = overS->find(seg1); SkOpPtT* e1 = overE->find(seg1); + if (approximately_equal_half(s1->fT, e1->fT)) { + return false; + } if (!s1->starter(e1)->span()->upCast()->windValue()) { s1 = overS->find(seg1o); e1 = overE->find(seg1o); if (!s1->starter(e1)->span()->upCast()->windValue()) { - return; + return true; } } SkOpPtT* s2 = overS->find(seg2); SkOpPtT* e2 = overE->find(seg2); + if (approximately_equal_half(s2->fT, e2->fT)) { + return false; + } if (!s2->starter(e2)->span()->upCast()->windValue()) { s2 = overS->find(seg2o); e2 = overE->find(seg2o); if (!s2->starter(e2)->span()->upCast()->windValue()) { - return; + return true; } } if (s1->segment() == s2->segment()) { - return; + return true; } if (s1->fT > e1->fT) { SkTSwap(s1, e1); SkTSwap(s2, e2); } this->add(s1, e1, s2, e2, allocator); + return true; } bool SkOpCoincidence::contains(const SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd, @@ -540,7 +547,7 @@ bool SkOpCoincidence::expand() { return expanded; } -void SkOpCoincidence::findOverlaps(SkOpCoincidence* overlaps, SkChunkAlloc* allocator) const { +bool SkOpCoincidence::findOverlaps(SkOpCoincidence* overlaps, SkChunkAlloc* allocator) const { overlaps->fHead = overlaps->fTop = nullptr; SkDEBUGCODE_(overlaps->debugSetGlobalState(fDebugState)); SkCoincidentSpans* outer = fHead; @@ -563,18 +570,21 @@ void SkOpCoincidence::findOverlaps(SkOpCoincidence* overlaps, SkChunkAlloc* allo || (outerOpp == innerOpp && SkOpPtT::Overlaps(outer->fOppPtTStart, outer->fOppPtTEnd, inner->fOppPtTStart, inner->fOppPtTEnd, &overlapS, &overlapE))) { - overlaps->addOverlap(outerCoin, outerOpp, innerCoin, innerOpp, - overlapS, overlapE, allocator); + if (!overlaps->addOverlap(outerCoin, outerOpp, innerCoin, innerOpp, + overlapS, overlapE, allocator)) { + return false; + } } } outer = outer->fNext; } + return true; } -void SkOpCoincidence::fixAligned() { +bool SkOpCoincidence::fixAligned() { SkCoincidentSpans* coin = fHead; if (!coin) { - return; + return true; } do { if (coin->fCoinPtTStart->deleted()) { @@ -593,6 +603,12 @@ void SkOpCoincidence::fixAligned() { coin = fHead; SkCoincidentSpans** priorPtr = &fHead; do { + if (coin->fCoinPtTStart == coin->fCoinPtTEnd) { + return false; + } + if (coin->fOppPtTStart == coin->fOppPtTEnd) { + return false; + } if (coin->fCoinPtTStart->collapsed(coin->fCoinPtTEnd) || coin->fOppPtTStart->collapsed(coin->fOppPtTEnd)) { *priorPtr = coin->fNext; @@ -600,6 +616,7 @@ void SkOpCoincidence::fixAligned() { } priorPtr = &coin->fNext; } while ((coin = coin->fNext)); + return true; } void SkOpCoincidence::fixUp(SkOpPtT* deleted, SkOpPtT* kept) { |