diff options
author | caryclark <caryclark@google.com> | 2016-06-08 04:28:19 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-06-08 04:28:19 -0700 |
commit | dae6b97705fde08958b1a36fa6ce685d28fc692c (patch) | |
tree | 39b7c096c331a0a29a43ddc7455705f821f5f640 /tests | |
parent | 2af4599b5c514933bf997d4837ddaaf24fc61cd7 (diff) |
fix pathops fuzz bugs
Fail out in a couple of new places when the input data is very
large and exceeds the limits of the pathops machinery.
Most of the change here plumbs in a way to exclude an assert in
one of these exceptional cases. The current SkAddIntersection
implementation and the inner functions it calls has no way to
report an error to the root caller for an early exit, so rather
than add that in, exclude the assert when the test that would
trigger it runs (allowing the test to otherwise ensure that it
properly fails).
TBR=reed@google.com
BUG=617586,617635
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2046713003
Review-Url: https://codereview.chromium.org/2046713003
Diffstat (limited to 'tests')
-rwxr-xr-x | tests/PathOpsAngleIdeas.cpp | 2 | ||||
-rw-r--r-- | tests/PathOpsAngleTest.cpp | 4 | ||||
-rw-r--r-- | tests/PathOpsBuilderTest.cpp | 22 | ||||
-rw-r--r-- | tests/PathOpsExtendedTest.cpp | 19 | ||||
-rw-r--r-- | tests/PathOpsExtendedTest.h | 2 | ||||
-rw-r--r-- | tests/PathOpsOpTest.cpp | 50 |
6 files changed, 90 insertions, 9 deletions
diff --git a/tests/PathOpsAngleIdeas.cpp b/tests/PathOpsAngleIdeas.cpp index 8fc100ee02..2e3c7b9066 100755 --- a/tests/PathOpsAngleIdeas.cpp +++ b/tests/PathOpsAngleIdeas.cpp @@ -419,7 +419,7 @@ static void testQuadAngles(skiatest::Reporter* reporter, const SkDQuad& quad1, c SkPoint shortQuads[2][3]; SkOpContourHead contour; - SkOpGlobalState state(nullptr, &contour SkDEBUGPARAMS(nullptr)); + SkOpGlobalState state(nullptr, &contour SkDEBUGPARAMS(false) SkDEBUGPARAMS(nullptr)); contour.init(&state, false, false); makeSegment(&contour, quad1, shortQuads[0], allocator); makeSegment(&contour, quad1, shortQuads[1], allocator); diff --git a/tests/PathOpsAngleTest.cpp b/tests/PathOpsAngleTest.cpp index faf5da50f2..6389c305bb 100644 --- a/tests/PathOpsAngleTest.cpp +++ b/tests/PathOpsAngleTest.cpp @@ -235,7 +235,7 @@ static const int circleDataSetSize = (int) SK_ARRAY_COUNT(circleDataSet); DEF_TEST(PathOpsAngleCircle, reporter) { SkChunkAlloc allocator(4096); SkOpContourHead contour; - SkOpGlobalState state(nullptr, &contour SkDEBUGPARAMS(nullptr)); + SkOpGlobalState state(nullptr, &contour SkDEBUGPARAMS(false) SkDEBUGPARAMS(nullptr)); contour.init(&state, false, false); for (int index = 0; index < circleDataSetSize; ++index) { CircleData& data = circleDataSet[index]; @@ -427,7 +427,7 @@ struct FourPoints { DEF_TEST(PathOpsAngleAfter, reporter) { SkChunkAlloc allocator(4096); SkOpContourHead contour; - SkOpGlobalState state(nullptr, &contour SkDEBUGPARAMS(nullptr)); + SkOpGlobalState state(nullptr, &contour SkDEBUGPARAMS(false) SkDEBUGPARAMS(nullptr)); contour.init(&state, false, false); for (int index = intersectDataSetsSize - 1; index >= 0; --index) { IntersectData* dataArray = intersectDataSets[index]; diff --git a/tests/PathOpsBuilderTest.cpp b/tests/PathOpsBuilderTest.cpp index e191ecee5e..e29b4bc473 100644 --- a/tests/PathOpsBuilderTest.cpp +++ b/tests/PathOpsBuilderTest.cpp @@ -301,3 +301,25 @@ DEF_TEST(Issue569540, reporter) { SkPath result; builder.resolve(&result); } + +DEF_TEST(SkOpBuilderFuzz665, reporter) { + SkPath path; + path.setFillType(SkPath::kEvenOdd_FillType); +path.moveTo(SkBits2Float(0xcc4264a7), SkBits2Float(0x4bb12e50)); // -5.0959e+07f, 2.32235e+07f +path.lineTo(SkBits2Float(0xcc4264b0), SkBits2Float(0x4bb12e48)); // -5.0959e+07f, 2.32234e+07f +path.lineTo(SkBits2Float(0xcc4264a7), SkBits2Float(0x4bb12e50)); // -5.0959e+07f, 2.32235e+07f +path.close(); + SkPath path1(path); + path.reset(); + path.setFillType(SkPath::kWinding_FillType); +path.moveTo(SkBits2Float(0x43213333), SkBits2Float(0x43080000)); // 161.2f, 136 +path.lineTo(SkBits2Float(0x43038000), SkBits2Float(0x43080000)); // 131.5f, 136 +path.cubicTo(SkBits2Float(0x43038000), SkBits2Float(0x42f00000), SkBits2Float(0x42f16666), SkBits2Float(0x42d53333), SkBits2Float(0x42d3cccd), SkBits2Float(0x42cd6666)); // 131.5f, 120, 120.7f, 106.6f, 105.9f, 102.7f +path.lineTo(SkBits2Float(0x42e33333), SkBits2Float(0x42940000)); // 113.6f, 74 + SkPath path2(path); + SkOpBuilder builder; + builder.add(path1, kUnion_SkPathOp); + builder.add(path2, kUnion_SkPathOp); + SkPath result; + builder.resolve(&result); +} diff --git a/tests/PathOpsExtendedTest.cpp b/tests/PathOpsExtendedTest.cpp index b5bf5b8d9f..572766086a 100644 --- a/tests/PathOpsExtendedTest.cpp +++ b/tests/PathOpsExtendedTest.cpp @@ -488,15 +488,17 @@ static void showName(const SkPath& a, const SkPath& b, const SkPathOp shapeOp) { #endif bool OpDebug(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result, - bool expectSuccess SkDEBUGPARAMS(const char* testName)); + bool expectSuccess SkDEBUGPARAMS(bool skipAssert) + SkDEBUGPARAMS(const char* testName)); static bool innerPathOp(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b, - const SkPathOp shapeOp, const char* testName, bool expectSuccess) { + const SkPathOp shapeOp, const char* testName, bool expectSuccess, bool skipAssert) { #if 0 && DEBUG_SHOW_TEST_NAME showName(a, b, shapeOp); #endif SkPath out; - if (!OpDebug(a, b, shapeOp, &out, expectSuccess SkDEBUGPARAMS(testName))) { + if (!OpDebug(a, b, shapeOp, &out, expectSuccess SkDEBUGPARAMS(skipAssert) + SkDEBUGPARAMS(testName))) { SkDebugf("%s did not expect failure\n", __FUNCTION__); REPORTER_ASSERT(reporter, 0); return false; @@ -536,17 +538,22 @@ static bool innerPathOp(skiatest::Reporter* reporter, const SkPath& a, const SkP bool testPathOp(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b, const SkPathOp shapeOp, const char* testName) { - return innerPathOp(reporter, a, b, shapeOp, testName, true); + return innerPathOp(reporter, a, b, shapeOp, testName, true, false); } bool testPathOpCheck(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b, const SkPathOp shapeOp, const char* testName, bool checkFail) { - return innerPathOp(reporter, a, b, shapeOp, testName, checkFail); + return innerPathOp(reporter, a, b, shapeOp, testName, checkFail, false); } bool testPathOpFailCheck(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b, const SkPathOp shapeOp, const char* testName) { - return innerPathOp(reporter, a, b, shapeOp, testName, false); + return innerPathOp(reporter, a, b, shapeOp, testName, false, false); +} + +bool testPathSkipAssertOp(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b, + const SkPathOp shapeOp, const char* testName) { + return innerPathOp(reporter, a, b, shapeOp, testName, true, true); } bool testPathFailOp(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b, diff --git a/tests/PathOpsExtendedTest.h b/tests/PathOpsExtendedTest.h index 17073833cb..0a6f4ab91f 100644 --- a/tests/PathOpsExtendedTest.h +++ b/tests/PathOpsExtendedTest.h @@ -44,6 +44,8 @@ extern bool testPathOpFailCheck(skiatest::Reporter* reporter, const SkPath& a, c const SkPathOp , const char* testName); extern bool testPathFailOp(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b, const SkPathOp , const char* testName); +extern bool testPathSkipAssertOp(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b, + const SkPathOp , const char* testName); extern bool testSimplify(SkPath& path, bool useXor, SkPath& out, PathOpsThreadState& state, const char* pathStr); extern bool testSimplify(skiatest::Reporter* reporter, const SkPath& path, const char* filename); diff --git a/tests/PathOpsOpTest.cpp b/tests/PathOpsOpTest.cpp index 00a8f52477..d75c9a6fb6 100644 --- a/tests/PathOpsOpTest.cpp +++ b/tests/PathOpsOpTest.cpp @@ -5836,7 +5836,57 @@ SkPath path2(path); testPathFailOp(reporter, path1, path2, (SkPathOp) 1, filename); } +static void fuzz1450_0(skiatest::Reporter* reporter, const char* filename) { +SkPath path; +path.moveTo(SkBits2Float(0x43b40000), SkBits2Float(0xcf000000)); // 360, -2.14748e+09f +path.conicTo(SkBits2Float(0x4e800002), SkBits2Float(0xcf000000), SkBits2Float(0x4e800002), SkBits2Float(0xce7ffffe), SkBits2Float(0x3f3504f4)); // 1.07374e+09f, -2.14748e+09f, 1.07374e+09f, -1.07374e+09f, 0.707107f +path.conicTo(SkBits2Float(0x4e800002), SkBits2Float(0x43800001), SkBits2Float(0x43348000), SkBits2Float(0x43800001), SkBits2Float(0x3f3504f4)); // 1.07374e+09f, 256, 180.5f, 256, 0.707107f +SkPath path1(path); +path.reset(); +path.moveTo(SkBits2Float(0x43b40000), SkBits2Float(0x45816000)); // 360, 4140 +path.conicTo(SkBits2Float(0x43b40005), SkBits2Float(0x458a945d), SkBits2Float(0x45610000), SkBits2Float(0x458a945d), SkBits2Float(0x3f3504f3)); // 360, 4434.55f, 3600, 4434.55f, 0.707107f +path.conicTo(SkBits2Float(0x45d5bfff), SkBits2Float(0x458a945d), SkBits2Float(0x45d5bfff), SkBits2Float(0x45816000), SkBits2Float(0x3f3504f3)); // 6840, 4434.55f, 6840, 4140, 0.707107f +path.lineTo(SkBits2Float(0x42c80000), SkBits2Float(0x44000000)); // 100, 512 +path.lineTo(SkBits2Float(0x42000000), SkBits2Float(0x41800000)); // 32, 16 +path.lineTo(SkBits2Float(0x43b40000), SkBits2Float(0x44800000)); // 360, 1024 +path.lineTo(SkBits2Float(0x43b40000), SkBits2Float(0x45816000)); // 360, 4140 +path.close(); +SkPath path2(path); +testPathSkipAssertOp(reporter, path1, path2, kUnion_SkPathOp, filename); +} + +static void fuzz1450_1(skiatest::Reporter* reporter, const char* filename) { +SkPath path; +path.setFillType(SkPath::kEvenOdd_FillType); +path.moveTo(SkBits2Float(0x4e800002), SkBits2Float(0xce7ffffe)); // 1.07374e+09f, -1.07374e+09f +path.conicTo(SkBits2Float(0x4e800002), SkBits2Float(0xcf000000), SkBits2Float(0x43b40000), SkBits2Float(0xcf000000), SkBits2Float(0x3f3504f4)); // 1.07374e+09f, -2.14748e+09f, 360, -2.14748e+09f, 0.707107f +path.lineTo(SkBits2Float(0x43348000), SkBits2Float(0x43800001)); // 180.5f, 256 +path.lineTo(SkBits2Float(0x42000000), SkBits2Float(0x41800000)); // 32, 16 +path.lineTo(SkBits2Float(0x42c80000), SkBits2Float(0x44000000)); // 100, 512 +path.lineTo(SkBits2Float(0x43553abd), SkBits2Float(0x440f3cbd)); // 213.229f, 572.949f +path.lineTo(SkBits2Float(0x43b40000), SkBits2Float(0x44800000)); // 360, 1024 +path.lineTo(SkBits2Float(0x43b40000), SkBits2Float(0x45816000)); // 360, 4140 +path.conicTo(SkBits2Float(0x43b40005), SkBits2Float(0x458a945d), SkBits2Float(0x45610000), SkBits2Float(0x458a945d), SkBits2Float(0x3f3504f3)); // 360, 4434.55f, 3600, 4434.55f, 0.707107f +path.conicTo(SkBits2Float(0x45d5bfff), SkBits2Float(0x458a945d), SkBits2Float(0x45d5bfff), SkBits2Float(0x45816000), SkBits2Float(0x3f3504f3)); // 6840, 4434.55f, 6840, 4140, 0.707107f +path.lineTo(SkBits2Float(0x43553abd), SkBits2Float(0x440f3cbd)); // 213.229f, 572.949f +path.lineTo(SkBits2Float(0x43348000), SkBits2Float(0x43800001)); // 180.5f, 256 +path.conicTo(SkBits2Float(0x4e800002), SkBits2Float(0x43800001), SkBits2Float(0x4e800002), SkBits2Float(0xce7ffffe), SkBits2Float(0x3f3504f4)); // 1.07374e+09f, 256, 1.07374e+09f, -1.07374e+09f, 0.707107f +path.close(); +SkPath path1(path); +path.reset(); +path.moveTo(SkBits2Float(0x42fe0000), SkBits2Float(0x43a08000)); // 127, 321 +path.lineTo(SkBits2Float(0x45d5c000), SkBits2Float(0x43870000)); // 6840, 270 +path.lineTo(SkBits2Float(0xd0a00000), SkBits2Float(0x4cbebc20)); // -2.14748e+10f, 1e+08 +path.lineTo(SkBits2Float(0x451f7000), SkBits2Float(0x42800000)); // 2551, 64 +path.lineTo(SkBits2Float(0x42fe0000), SkBits2Float(0x43a08000)); // 127, 321 +path.close(); +SkPath path2(path); +testPathFailOp(reporter, path1, path2, kUnion_SkPathOp, filename); +} + static struct TestDesc failTests[] = { + TEST(fuzz1450_1), + TEST(fuzz1450_0), TEST(bug597926_0), TEST(fuzz535151), TEST(fuzz753_91), |