limit addEndMoveSpans loop in pathops
authorCary Clark <caryclark@skia.org>
Wed, 8 Mar 2017 22:11:12 +0000 (17:11 -0500)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Thu, 9 Mar 2017 14:11:11 +0000 (14:11 +0000)
Prevent addEndMoveSpans from looping
forever and abort with an error
if the loop count is crazy big.

R=kjlubick@google.com
BUG=684553

Change-Id: I16c250c0b2f88534f809aba17a18081aea4e1f44
Reviewed-on: https://skia-review.googlesource.com/9458
Reviewed-by: Cary Clark <caryclark@google.com>
Commit-Queue: Cary Clark <caryclark@google.com>

src/pathops/SkOpCoincidence.cpp
tests/PathOpsOpTest.cpp

index b4854a8..93a6d66 100644 (file)
@@ -278,7 +278,11 @@ bool SkOpCoincidence::addEndMovedSpans(const SkOpSpan* base, const SkOpSpanBase*
     const SkOpPtT* testPtT = testSpan->ptT();
     const SkOpPtT* stopPtT = testPtT;
     const SkOpSegment* baseSeg = base->segment();
+    int escapeHatch = 100000;  // this is 100 times larger than the debugLoopLimit test
     while ((testPtT = testPtT->next()) != stopPtT) {
+        if (--escapeHatch <= 0) {
+            return false;  // if triggered (likely by a fuzz-generated test) too complex to succeed
+        }
         const SkOpSegment* testSeg = testPtT->segment();
         if (testPtT->deleted()) {
             continue;
index 2f431c7..4e8cf25 100644 (file)
@@ -8450,7 +8450,46 @@ path.quadTo(SkBits2Float(0xd4d40000), SkBits2Float(0xd4d4d4d4), SkBits2Float(0xd
     testPathOpFuzz(reporter, path1, path2, (SkPathOp) 2, filename);
 }
 
+static void fuzzhang_2(skiatest::Reporter* reporter, const char* filename) {\r
+    SkPath path;\r
+    path.setFillType((SkPath::FillType) 0);\r
+path.setFillType(SkPath::kWinding_FillType);\r
+path.moveTo(SkBits2Float(0x5568392a), SkBits2Float(0x72837268));  // 1.59583e+13f, 5.20715e+30f\r
+path.quadTo(SkBits2Float(0xe0e02972), SkBits2Float(0xe0e060e0), SkBits2Float(0x728e4603), SkBits2Float(0x72727272));  // -1.29221e+20f, -1.29345e+20f, 5.63603e+30f, 4.80216e+30f\r
+path.lineTo(SkBits2Float(0x5568392a), SkBits2Float(0x72837268));  // 1.59583e+13f, 5.20715e+30f\r
+path.close();\r
+path.moveTo(SkBits2Float(0x5568392a), SkBits2Float(0x72837268));  // 1.59583e+13f, 5.20715e+30f\r
+path.quadTo(SkBits2Float(0x68720052), SkBits2Float(0x52527372), SkBits2Float(0x00527252), SkBits2Float(0x728e4601));  // 4.57127e+24f, 2.2597e+11f, 7.57152e-39f, 5.63603e+30f\r
+path.quadTo(SkBits2Float(0x52ec7272), SkBits2Float(0x6265527f), SkBits2Float(0x8e460152), SkBits2Float(0x72ff8072));  // 5.07766e+11f, 1.05756e+21f, -2.4406e-30f, 1.01215e+31f\r
+path.lineTo(SkBits2Float(0x5568392a), SkBits2Float(0x72837268));  // 1.59583e+13f, 5.20715e+30f\r
+path.close();\r
+path.moveTo(SkBits2Float(0x5568392a), SkBits2Float(0x72837268));  // 1.59583e+13f, 5.20715e+30f\r
+path.lineTo(SkBits2Float(0x52626552), SkBits2Float(0x72727272));  // 2.43091e+11f, 4.80216e+30f\r
+path.quadTo(SkBits2Float(0x72727272), SkBits2Float(0x62727272), SkBits2Float(0x39393939), SkBits2Float(0x728bc739));  // 4.80216e+30f, 1.11809e+21f, 0.000176643f, 5.53719e+30f\r
+path.cubicTo(SkBits2Float(0x72728092), SkBits2Float(0x72727260), SkBits2Float(0x4d727272), SkBits2Float(0x5252522a), SkBits2Float(0x72735252), SkBits2Float(0x72707272));  // 4.80325e+30f, 4.80215e+30f, 2.54224e+08f, 2.2583e+11f, 4.81948e+30f, 4.76254e+30f\r
+path.quadTo(SkBits2Float(0x72727272), SkBits2Float(0x56727272), SkBits2Float(0x72720152), SkBits2Float(0x72727270));  // 4.80216e+30f, 6.66433e+13f, 4.79341e+30f, 4.80216e+30f\r
+path.quadTo(SkBits2Float(0x52526172), SkBits2Float(0x8e460300), SkBits2Float(0x72727272), SkBits2Float(0x52525272));  // 2.25894e+11f, -2.44068e-30f, 4.80216e+30f, 2.25832e+11f\r
+path.conicTo(SkBits2Float(0xb5727272), SkBits2Float(0x7f2b727f), SkBits2Float(0x607272ff), SkBits2Float(0x72727276), SkBits2Float(0x2a527272));  // -9.03186e-07f, 2.27892e+38f, 6.98812e+19f, 4.80216e+30f, 1.86915e-13f\r
+path.lineTo(SkBits2Float(0x5568392a), SkBits2Float(0x72837268));  // 1.59583e+13f, 5.20715e+30f\r
+path.close();\r
+path.moveTo(SkBits2Float(0x5568392a), SkBits2Float(0x72837268));  // 1.59583e+13f, 5.20715e+30f\r
+path.lineTo(SkBits2Float(0x72727272), SkBits2Float(0x52525f72));  // 4.80216e+30f, 2.25886e+11f\r
+path.lineTo(SkBits2Float(0x5568392a), SkBits2Float(0x72837268));  // 1.59583e+13f, 5.20715e+30f\r
+path.close();\r
+path.moveTo(SkBits2Float(0x5568392a), SkBits2Float(0x72837268));  // 1.59583e+13f, 5.20715e+30f\r
+path.quadTo(SkBits2Float(0x52727272), SkBits2Float(0x64655252), SkBits2Float(0x72c1c152), SkBits2Float(0x72727272));  // 2.60326e+11f, 1.69209e+22f, 7.67543e+30f, 4.80216e+30f\r
+\r
+    SkPath path1(path);\r
+    path.reset();\r
+    path.setFillType((SkPath::FillType) 0);\r
+path.setFillType(SkPath::kWinding_FillType);\r
+\r
+    SkPath path2(path);\r
+    testPathOpFail(reporter, path1, path2, (SkPathOp) 1, filename);\r
+}\r
+
 static struct TestDesc failTests[] = {
+    TEST(fuzzhang_2),
     TEST(release_13),
     TEST(fuzzhang_1),
     TEST(fuzz763_57),