abort really big path fuzzing

This adds a couple of special cases
to stop the fuzzer from timing out.

The first occurs when the fuzzer generates
a very large path with very large quads.
Count the subdivisions and stop after a while.

The second occurs with a normal path and
1D path effect with a very small advance.
Count the points and stop after a while.

R=reed@google.com,bsalomon@google.com,kjlubick@google.com
Bug: oss-fuzz:8349,oss-fuzz:8805
Change-Id: I86130e3f512f48e5a39335412435eabc245ed193
Reviewed-on: https://skia-review.googlesource.com/135709
Reviewed-by: Kevin Lubick <kjlubick@google.com>
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Reed <reed@google.com>
Auto-Submit: Cary Clark <caryclark@skia.org>
diff --git a/include/core/SkPathMeasure.h b/include/core/SkPathMeasure.h
index 287c292..e506c42 100644
--- a/include/core/SkPathMeasure.h
+++ b/include/core/SkPathMeasure.h
@@ -90,7 +90,9 @@
     unsigned        fFirstPtIndex;      // relative to the current contour
     bool            fIsClosed;          // relative to the current contour
     bool            fForceClosed;
-
+#if defined(IS_FUZZING_WITH_LIBFUZZER)
+    int             fSubdivisionsMax;
+#endif
     struct Segment {
         SkScalar    fDistance;  // total distance up to this point
         unsigned    fPtIndex; // index into the fPts array
diff --git a/src/core/SkPathMeasure.cpp b/src/core/SkPathMeasure.cpp
index 905c176..e69ea49 100644
--- a/src/core/SkPathMeasure.cpp
+++ b/src/core/SkPathMeasure.cpp
@@ -231,6 +231,9 @@
 
 SkScalar SkPathMeasure::compute_quad_segs(const SkPoint pts[3],
                           SkScalar distance, int mint, int maxt, unsigned ptIndex) {
+#if defined(IS_FUZZING_WITH_LIBFUZZER)
+    --fSubdivisionsMax;
+#endif
     if (tspan_big_enough(maxt - mint) && quad_too_curvy(pts)) {
         SkPoint tmp[5];
         int     halft = (mint + maxt) >> 1;
@@ -256,6 +259,9 @@
 SkScalar SkPathMeasure::compute_conic_segs(const SkConic& conic, SkScalar distance,
                                            int mint, const SkPoint& minPt,
                                            int maxt, const SkPoint& maxPt, unsigned ptIndex) {
+#if defined(IS_FUZZING_WITH_LIBFUZZER)
+    --fSubdivisionsMax;
+#endif
     int halft = (mint + maxt) >> 1;
     SkPoint halfPt = conic.evalAt(tValue2Scalar(halft));
     if (!halfPt.isFinite()) {
@@ -281,6 +287,9 @@
 
 SkScalar SkPathMeasure::compute_cubic_segs(const SkPoint pts[4],
                            SkScalar distance, int mint, int maxt, unsigned ptIndex) {
+#if defined(IS_FUZZING_WITH_LIBFUZZER)
+    --fSubdivisionsMax;
+#endif
     if (tspan_big_enough(maxt - mint) && cubic_too_curvy(pts)) {
         SkPoint tmp[7];
         int     halft = (mint + maxt) >> 1;
@@ -320,6 +329,9 @@
      */
     fSegments.reset();
     bool done = false;
+ #if defined(IS_FUZZING_WITH_LIBFUZZER)
+    fSubdivisionsMax = 10000000;
+#endif
     do {
         switch (fIter.next(pts)) {
             case SkPath::kMove_Verb:
@@ -401,6 +413,13 @@
                 done = true;
                 break;
         }
+#if defined(IS_FUZZING_WITH_LIBFUZZER)
+        if (fSubdivisionsMax < 0) {
+            fLength = 0;
+            return;
+        }
+#endif
+
     } while (!done);
 
     fLength = distance;
@@ -681,6 +700,11 @@
 */
 bool SkPathMeasure::nextContour() {
     (void)this->getLength();    // make sure we measure the current contour
+#if defined(IS_FUZZING_WITH_LIBFUZZER)
+    if (fSubdivisionsMax < 0) {
+        return false;
+    }
+#endif
     fLength = -1;               // now signal that we should build the next set of segments
     return this->getLength() > 0;
 }
diff --git a/src/effects/Sk1DPathEffect.cpp b/src/effects/Sk1DPathEffect.cpp
index 1837479..bad6ced 100644
--- a/src/effects/Sk1DPathEffect.cpp
+++ b/src/effects/Sk1DPathEffect.cpp
@@ -171,6 +171,11 @@
 
 SkScalar SkPath1DPathEffect::next(SkPath* dst, SkScalar distance,
                                   SkPathMeasure& meas) const {
+#if defined(IS_FUZZING_WITH_LIBFUZZER)
+    if (dst->countPoints() > 100000) {
+        return fAdvance;
+    }
+#endif
     switch (fStyle) {
         case kTranslate_Style: {
             SkPoint pos;