diff options
author | Cary Clark <caryclark@skia.org> | 2018-06-19 10:47:15 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-06-21 16:42:37 +0000 |
commit | 472ab81032ccb67a4db295d694ca03d3c75cbda6 (patch) | |
tree | 72de4eb3328cb0cb6336c42f241865bfbda47fb6 | |
parent | 9ffe3dc24560297982002234c3e3a03a941f46a9 (diff) |
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>
-rw-r--r-- | include/core/SkPathMeasure.h | 4 | ||||
-rw-r--r-- | src/core/SkPathMeasure.cpp | 24 | ||||
-rw-r--r-- | src/effects/Sk1DPathEffect.cpp | 5 |
3 files changed, 32 insertions, 1 deletions
diff --git a/include/core/SkPathMeasure.h b/include/core/SkPathMeasure.h index 287c292aeb..e506c42298 100644 --- a/include/core/SkPathMeasure.h +++ b/include/core/SkPathMeasure.h @@ -90,7 +90,9 @@ private: 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 905c176b40..e69ea49521 100644 --- a/src/core/SkPathMeasure.cpp +++ b/src/core/SkPathMeasure.cpp @@ -231,6 +231,9 @@ static SkScalar compute_quad_len(const SkPoint pts[3]) { 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_quad_segs(const SkPoint pts[3], 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_conic_segs(const SkConic& conic, SkScalar distan 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 @@ void SkPathMeasure::buildSegments() { */ 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 @@ void SkPathMeasure::buildSegments() { 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::isClosed() { */ 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 1837479147..bad6ced508 100644 --- a/src/effects/Sk1DPathEffect.cpp +++ b/src/effects/Sk1DPathEffect.cpp @@ -171,6 +171,11 @@ void SkPath1DPathEffect::flatten(SkWriteBuffer& buffer) const { 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; |