fix fuzzing empty contours squirrelly cubics
authorCary Clark <caryclark@google.com>
Fri, 16 Dec 2016 21:31:11 +0000 (16:31 -0500)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Fri, 16 Dec 2016 22:07:31 +0000 (22:07 +0000)
The fuzzer triggered relatively new code that
missized the split cubic array, i.e., if a cubic
is split in three places it makes four cubics.

The fuzzer triggered other relative new code
that permits a contour to be empty. This happens
when a line crosses over itself but doesn't
enclose anything.

R=kjlubick@google.com
BUG=skia:6061

Change-Id: I0c04d0d390ff1092f7b3bb28ebbfca517451f497
Reviewed-on: https://skia-review.googlesource.com/6223
Commit-Queue: Cary Clark <caryclark@google.com>
Reviewed-by: Kevin Lubick <kjlubick@google.com>
src/pathops/SkOpContour.cpp
src/pathops/SkOpEdgeBuilder.cpp
src/pathops/SkPathOpsWinding.cpp

index fbe9f4db4b8d69eea4821757b0b8b47f7c50a1fb..98467c558ceb645db7fc77f9f2ef515d3c3143f2 100644 (file)
@@ -11,6 +11,9 @@
 #include "SkTSort.h"
 
 void SkOpContour::toPath(SkPathWriter* path) const {
+    if (!this->count()) {
+        return;
+    }
     const SkOpSegment* segment = &fHead;
     do {
         SkAssertResult(segment->addCurveTo(segment->head(), segment->tail(), path));
index 77c949b17bbdaf0056156f0f934c543f725c90da..120a50322750174baae207924d131245cc813c8f 100644 (file)
@@ -277,8 +277,9 @@ bool SkOpEdgeBuilder::walk() {
                         SkPoint fReduced[4];
                         SkPath::Verb fVerb;
                         bool fCanAdd;
-                    } splits[3];
-                    SkASSERT(SK_ARRAY_COUNT(splits) == SK_ARRAY_COUNT(splitT));
+                    } splits[4];
+                    SkASSERT(SK_ARRAY_COUNT(splits) == SK_ARRAY_COUNT(splitT) + 1);
+                    SkTQSort(splitT, &splitT[breaks - 1]);
                     for (int index = 0; index <= breaks; ++index) {
                         Splitsville* split = &splits[index];
                         split->fT[0] = index ? splitT[index - 1] : 0;
index 35cabcf62e4200150e8fabcbe71a809521f7dcdb..cec9a22e20d482bd1279b380da94de4036e1b090 100644 (file)
@@ -381,18 +381,20 @@ SkOpSpan* SkOpSegment::findSortableTop(SkOpContour* contourHead) {
 }
 
 SkOpSpan* SkOpContour::findSortableTop(SkOpContour* contourHead) {
-    SkOpSegment* testSegment = &fHead;
     bool allDone = true;
-    do {
-        if (testSegment->done()) {
-            continue;
-        }
-        allDone = false;
-        SkOpSpan* result = testSegment->findSortableTop(contourHead);
-        if (result) {
-            return result;
-        }
-    } while ((testSegment = testSegment->next()));
+    if (fCount) {
+        SkOpSegment* testSegment = &fHead;
+        do {
+            if (testSegment->done()) {
+                continue;
+            }
+            allDone = false;
+            SkOpSpan* result = testSegment->findSortableTop(contourHead);
+            if (result) {
+                return result;
+            }
+        } while ((testSegment = testSegment->next()));
+    }
     if (allDone) {
       fDone = true;
     }