aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Cary Clark <caryclark@skia.org>2018-06-19 10:47:15 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-06-21 16:42:37 +0000
commit472ab81032ccb67a4db295d694ca03d3c75cbda6 (patch)
tree72de4eb3328cb0cb6336c42f241865bfbda47fb6
parent9ffe3dc24560297982002234c3e3a03a941f46a9 (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.h4
-rw-r--r--src/core/SkPathMeasure.cpp24
-rw-r--r--src/effects/Sk1DPathEffect.cpp5
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;