conic fuzz fix
If no closest section is found in conic intersection (which can happen if the numbers are out of range) abort the intersection. Also suppress assert fired in this case so it only checks intersections with in-range values. TBR=reed@google.com BUG=630378 GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2166813006 Review-Url: https://codereview.chromium.org/2166813006
This commit is contained in:
parent
901257a3ba
commit
cdeff81bdb
@ -882,6 +882,7 @@ bool SkTSect<TCurve, OppCurve>::binarySearchCoin(SkTSect<OppCurve, TCurve>* sect
|
||||
SkDPoint last = fCurve.ptAtT(tStart);
|
||||
SkDPoint oppPt;
|
||||
bool flip = false;
|
||||
bool contained = false;
|
||||
SkDEBUGCODE(bool down = tStep < 0);
|
||||
const OppCurve& opp = sect2->fCurve;
|
||||
do {
|
||||
@ -908,6 +909,7 @@ bool SkTSect<TCurve, OppCurve>::binarySearchCoin(SkTSect<OppCurve, TCurve>* sect
|
||||
if (sect2->fHead->contains(oppTTest)) {
|
||||
*oppT = oppTTest;
|
||||
oppPt = work.fCoinStart.perpPt();
|
||||
contained = true;
|
||||
SkASSERT(down ? result > work.fStartT : result < work.fStartT);
|
||||
result = work.fStartT;
|
||||
continue;
|
||||
@ -916,6 +918,9 @@ bool SkTSect<TCurve, OppCurve>::binarySearchCoin(SkTSect<OppCurve, TCurve>* sect
|
||||
tStep = -tStep;
|
||||
flip = true;
|
||||
} while (true);
|
||||
if (!contained) {
|
||||
return false;
|
||||
}
|
||||
if (last.approximatelyEqual(fCurve[0])) {
|
||||
result = 0;
|
||||
} else if (last.approximatelyEqual(fCurve[TCurve::kPointLast])) {
|
||||
@ -1923,10 +1928,10 @@ struct SkClosestRecord {
|
||||
fClosest = dist;
|
||||
}
|
||||
|
||||
bool matesWith(const SkClosestRecord& mate) const {
|
||||
bool matesWith(const SkClosestRecord& mate SkDEBUGPARAMS(SkIntersections* i)) const {
|
||||
SkASSERT(fC1Span == mate.fC1Span || fC1Span->endT() <= mate.fC1Span->startT()
|
||||
|| mate.fC1Span->endT() <= fC1Span->startT());
|
||||
SkASSERT(fC2Span == mate.fC2Span || fC2Span->endT() <= mate.fC2Span->startT()
|
||||
SkOPOBJASSERT(i, fC2Span == mate.fC2Span || fC2Span->endT() <= mate.fC2Span->startT()
|
||||
|| mate.fC2Span->endT() <= fC2Span->startT());
|
||||
return fC1Span == mate.fC1Span || fC1Span->endT() == mate.fC1Span->startT()
|
||||
|| fC1Span->startT() == mate.fC1Span->endT()
|
||||
@ -1975,7 +1980,8 @@ struct SkClosestSect {
|
||||
fClosest.push_back().reset();
|
||||
}
|
||||
|
||||
bool find(const SkTSpan<TCurve, OppCurve>* span1, const SkTSpan<OppCurve, TCurve>* span2) {
|
||||
bool find(const SkTSpan<TCurve, OppCurve>* span1, const SkTSpan<OppCurve, TCurve>* span2
|
||||
SkDEBUGPARAMS(SkIntersections* i)) {
|
||||
SkClosestRecord<TCurve, OppCurve>* record = &fClosest[fUsed];
|
||||
record->findEnd(span1, span2, 0, 0);
|
||||
record->findEnd(span1, span2, 0, OppCurve::kPointLast);
|
||||
@ -1986,7 +1992,7 @@ struct SkClosestSect {
|
||||
}
|
||||
for (int index = 0; index < fUsed; ++index) {
|
||||
SkClosestRecord<TCurve, OppCurve>* test = &fClosest[index];
|
||||
if (test->matesWith(*record)) {
|
||||
if (test->matesWith(*record SkDEBUGPARAMS(i))) {
|
||||
if (test->fClosest > record->fClosest) {
|
||||
test->merge(*record);
|
||||
}
|
||||
@ -2212,7 +2218,7 @@ void SkTSect<TCurve, OppCurve>::BinarySearch(SkTSect<TCurve, OppCurve>* sect1,
|
||||
SkTSpan<OppCurve, TCurve>* result2 = sect2->fHead;
|
||||
bool found = false;
|
||||
while (result2) {
|
||||
found |= closest.find(result1, result2);
|
||||
found |= closest.find(result1, result2 SkDEBUGPARAMS(intersections));
|
||||
result2 = result2->fNext;
|
||||
}
|
||||
} while ((result1 = result1->fNext));
|
||||
|
@ -183,9 +183,14 @@ private:
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
#define SkOPASSERT(cond) SkASSERT(this->globalState()->debugSkipAssert() || cond)
|
||||
#define SkOPOBJASSERT(obj, cond) SkASSERT((obj->debugGlobalState() && \
|
||||
obj->debugGlobalState()->debugSkipAssert()) || cond)
|
||||
#else
|
||||
#define SkOPASSERT(cond)
|
||||
#define SkOPOBJASSERT(obj, cond)
|
||||
#endif
|
||||
|
||||
// Use Almost Equal when comparing coordinates. Use epsilon to compare T values.
|
||||
bool AlmostEqualUlps(float a, float b);
|
||||
|
@ -6533,7 +6533,52 @@ SkPath path2(path);
|
||||
testPathOpFail(reporter, path1, path2, kXOR_SkPathOp, filename);
|
||||
}
|
||||
|
||||
static void fuzz763_10(skiatest::Reporter* reporter, const char* filename) {
|
||||
SkPath path;
|
||||
path.setFillType((SkPath::FillType) 1);
|
||||
path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0x68556829)); // 0, 4.03114e+24f
|
||||
path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000)); // 0, 0
|
||||
path.quadTo(SkBits2Float(0x6a4b7bc0), SkBits2Float(0x00000000), SkBits2Float(0x00000000), SkBits2Float(0x6a4b7bc4)); // 6.14991e+25f, 0, 0, 6.14991e+25f
|
||||
path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0x68556829)); // 0, 4.03114e+24f
|
||||
path.close();
|
||||
|
||||
SkPath path1(path);
|
||||
path.reset();
|
||||
path.setFillType((SkPath::FillType) 0);
|
||||
path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000)); // 0, 0
|
||||
path.lineTo(SkBits2Float(0x5b2d2968), SkBits2Float(0x2a8c8f55)); // 4.87407e+16f, 2.49685e-13f
|
||||
path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000)); // 0, 0
|
||||
path.close();
|
||||
path.moveTo(SkBits2Float(0xc021211f), SkBits2Float(0x6a4b7b03)); // -2.51765f, 6.14982e+25f
|
||||
path.conicTo(SkBits2Float(0x682d2fed), SkBits2Float(0x755b6829), SkBits2Float(0x5b292d2b), SkBits2Float(0xc92a8c55), SkBits2Float(0x081f2a21)); // 3.27141e+24f, 2.78131e+32f, 4.76189e+16f, -698565, 4.78968e-34f
|
||||
path.lineTo(SkBits2Float(0xc021211f), SkBits2Float(0x6a4b7b03)); // -2.51765f, 6.14982e+25f
|
||||
path.close();
|
||||
path.moveTo(SkBits2Float(0xc021211f), SkBits2Float(0x6a4b7b03)); // -2.51765f, 6.14982e+25f
|
||||
path.conicTo(SkBits2Float(0x6a4b7bc0), SkBits2Float(0x2a8ced7a), SkBits2Float(0x21081f21), SkBits2Float(0x3a7bc003), SkBits2Float(0x47ed7a29)); // 6.14991e+25f, 2.50338e-13f, 4.61198e-19f, 0.00096035f, 121588
|
||||
path.lineTo(SkBits2Float(0xc021211f), SkBits2Float(0x6a4b7b03)); // -2.51765f, 6.14982e+25f
|
||||
path.close();
|
||||
path.moveTo(SkBits2Float(0xc021211f), SkBits2Float(0x6a4b7b03)); // -2.51765f, 6.14982e+25f
|
||||
path.quadTo(SkBits2Float(0x6829682d), SkBits2Float(0x292d555b), SkBits2Float(0x2a8c555b), SkBits2Float(0x081f2a29)); // 3.20001e+24f, 3.84878e-14f, 2.49282e-13f, 4.78969e-34f
|
||||
path.conicTo(SkBits2Float(0x6a497b19), SkBits2Float(0x218ced7a), SkBits2Float(0x0321081f), SkBits2Float(0x6a3a7bc0), SkBits2Float(0x47ed3a7a)); // 6.08939e+25f, 9.54963e-19f, 4.7323e-37f, 5.63611e+25f, 121461
|
||||
path.lineTo(SkBits2Float(0xc021211f), SkBits2Float(0x6a4b7b03)); // -2.51765f, 6.14982e+25f
|
||||
path.close();
|
||||
path.moveTo(SkBits2Float(0xc021211f), SkBits2Float(0x6a4b7b03)); // -2.51765f, 6.14982e+25f
|
||||
path.quadTo(SkBits2Float(0x282a282a), SkBits2Float(0x8a3a21df), SkBits2Float(0x2728282a), SkBits2Float(0x8a3a2129)); // 9.4456e-15f, -8.96194e-33f, 2.33365e-15f, -8.96181e-33f
|
||||
path.quadTo(SkBits2Float(0x8a284f9a), SkBits2Float(0x3a3ac2b3), SkBits2Float(0x2a292827), SkBits2Float(0x962be61d)); // -8.10388e-33f, 0.000712435f, 1.50241e-13f, -1.38859e-25f
|
||||
path.lineTo(SkBits2Float(0x272a802a), SkBits2Float(0x2a8c2d29)); // 2.36617e-15f, 2.49003e-13f
|
||||
path.lineTo(SkBits2Float(0xc021211f), SkBits2Float(0x6a4b7b03)); // -2.51765f, 6.14982e+25f
|
||||
path.close();
|
||||
path.moveTo(SkBits2Float(0x4f9a3a29), SkBits2Float(0x3ab38a28)); // 5.17501e+09f, 0.00136978f
|
||||
path.quadTo(SkBits2Float(0xc368305b), SkBits2Float(0x5b296855), SkBits2Float(0x2d8c5568), SkBits2Float(0x1f2a2172)); // -232.189f, 4.7684e+16f, 1.59541e-11f, 3.60266e-20f
|
||||
path.lineTo(SkBits2Float(0x29c00321), SkBits2Float(0x5b4b7b13)); // 8.52706e-14f, 5.72747e+16f
|
||||
|
||||
SkPath path2(path);
|
||||
testPathOpSkipAssert(reporter, path1, path2, (SkPathOp) 4, filename);
|
||||
}
|
||||
|
||||
|
||||
static struct TestDesc failTests[] = {
|
||||
TEST(fuzz763_10),
|
||||
TEST(kfuzz2),
|
||||
TEST(fuzz763_7),
|
||||
TEST(fuzz763_6),
|
||||
|
Loading…
Reference in New Issue
Block a user