From 91390c8acea911d747548e24031888a9c63650fe Mon Sep 17 00:00:00 2001 From: Cary Clark Date: Fri, 9 Mar 2018 14:02:46 -0500 Subject: pathmeasure fuzzer R=kjlubick@google.com, reed@google.com Bug: skia: Change-Id: I16a8b09312e5d1d1783bd6a4b791636ad8f63889 Reviewed-on: https://skia-review.googlesource.com/113165 Reviewed-by: Mike Reed Reviewed-by: Kevin Lubick Commit-Queue: Cary Clark --- fuzz/FuzzCanvas.cpp | 12 ++--- fuzz/FuzzCommon.cpp | 104 ++++++++++++++++++++++++++++++++++++ fuzz/FuzzCommon.h | 60 ++++----------------- fuzz/FuzzPathMeasure.cpp | 35 ++++++++++++ fuzz/FuzzPathop.cpp | 48 +---------------- fuzz/oss_fuzz/FuzzRegionSetPath.cpp | 2 +- 6 files changed, 158 insertions(+), 103 deletions(-) create mode 100644 fuzz/FuzzCommon.cpp create mode 100644 fuzz/FuzzPathMeasure.cpp (limited to 'fuzz') diff --git a/fuzz/FuzzCanvas.cpp b/fuzz/FuzzCanvas.cpp index 42e31b6a4e..783306b22f 100644 --- a/fuzz/FuzzCanvas.cpp +++ b/fuzz/FuzzCanvas.cpp @@ -447,7 +447,7 @@ static sk_sp make_fuzz_patheffect(Fuzz* fuzz, int depth) { } case 3: { SkPath path; - fuzz_path(fuzz, &path, 20); + FuzzPath(fuzz, &path, 20); SkScalar advance, phase; fuzz->next(&advance, &phase); SkPath1DPathEffect::Style style; @@ -462,7 +462,7 @@ static sk_sp make_fuzz_patheffect(Fuzz* fuzz, int depth) { } case 5: { SkPath path; - fuzz_path(fuzz, &path, 20); + FuzzPath(fuzz, &path, 20); SkMatrix matrix; fuzz->next(&matrix); return SkPath2DPathEffect::Make(matrix, path); @@ -1244,7 +1244,7 @@ static void fuzz_canvas(Fuzz* fuzz, SkCanvas* canvas, int depth = 9) { } case 21: { SkPath path; - fuzz_path(fuzz, &path, 30); + FuzzPath(fuzz, &path, 30); int op; bool doAntiAlias; fuzz->next(&doAntiAlias); @@ -1327,7 +1327,7 @@ static void fuzz_canvas(Fuzz* fuzz, SkCanvas* canvas, int depth = 9) { } case 32: { SkPath path; - fuzz_path(fuzz, &path, 60); + FuzzPath(fuzz, &path, 60); canvas->drawPath(path, paint); break; } @@ -1583,7 +1583,7 @@ static void fuzz_canvas(Fuzz* fuzz, SkCanvas* canvas, int depth = 9) { fuzz_paint_text_encoding(fuzz, &paint); SkTDArray text = make_fuzz_text(fuzz, paint); SkPath path; - fuzz_path(fuzz, &path, 20); + FuzzPath(fuzz, &path, 20); SkScalar hOffset, vOffset; fuzz->next(&hOffset, &vOffset); canvas->drawTextOnPathHV(text.begin(), SkToSizeT(text.count()), path, hOffset, @@ -1601,7 +1601,7 @@ static void fuzz_canvas(Fuzz* fuzz, SkCanvas* canvas, int depth = 9) { fuzz_paint_text_encoding(fuzz, &paint); SkTDArray text = make_fuzz_text(fuzz, paint); SkPath path; - fuzz_path(fuzz, &path, 20); + FuzzPath(fuzz, &path, 20); canvas->drawTextOnPath(text.begin(), SkToSizeT(text.count()), path, useMatrix ? &matrix : nullptr, paint); break; diff --git a/fuzz/FuzzCommon.cpp b/fuzz/FuzzCommon.cpp new file mode 100644 index 0000000000..51e2d18518 --- /dev/null +++ b/fuzz/FuzzCommon.cpp @@ -0,0 +1,104 @@ +/* + * Copyright 2018 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "Fuzz.h" +#include "FuzzCommon.h" + +// allows some float values for path points +void FuzzPath(Fuzz* fuzz, SkPath* path, int maxOps) { + if (maxOps < 2) { + maxOps = 2; + } + uint8_t fillType; + fuzz->nextRange(&fillType, 0, (uint8_t)SkPath::kInverseEvenOdd_FillType); + path->setFillType((SkPath::FillType)fillType); + uint8_t numOps; + fuzz->nextRange(&numOps, 2, maxOps); + for (uint8_t i = 0; i < numOps; ++i) { + uint8_t op; + fuzz->nextRange(&op, 0, 6); + SkScalar a, b, c, d, e, f; + switch (op) { + case 0: + fuzz_nice_float(fuzz, &a, &b); + path->moveTo(a, b); + break; + case 1: + fuzz_nice_float(fuzz, &a, &b); + path->lineTo(a, b); + break; + case 2: + fuzz_nice_float(fuzz, &a, &b, &c, &d); + path->quadTo(a, b, c, d); + break; + case 3: + fuzz_nice_float(fuzz, &a, &b, &c, &d, &e); + path->conicTo(a, b, c, d, e); + break; + case 4: + fuzz_nice_float(fuzz, &a, &b, &c, &d, &e, &f); + path->cubicTo(a, b, c, d, e, f); + break; + case 5: + fuzz_nice_float(fuzz, &a, &b, &c, &d, &e); + path->arcTo(a, b, c, d, e); + break; + case 6: + path->close(); + break; + default: + SkASSERT(false); + break; + } + } +} + +// allows all float values for path points +void BuildPath(Fuzz* fuzz, SkPath* path, int last_verb) { + while (!fuzz->exhausted()) { + // Use a uint8_t to conserve bytes. This makes our "fuzzed bytes footprint" + // smaller, which leads to more efficient fuzzing. + uint8_t operation; + fuzz->next(&operation); + SkScalar a,b,c,d,e,f; + + switch (operation % (last_verb + 1)) { + case SkPath::Verb::kMove_Verb: + fuzz->next(&a, &b); + path->moveTo(a, b); + break; + + case SkPath::Verb::kLine_Verb: + fuzz->next(&a, &b); + path->lineTo(a, b); + break; + + case SkPath::Verb::kQuad_Verb: + fuzz->next(&a, &b, &c, &d); + path->quadTo(a, b, c, d); + break; + + case SkPath::Verb::kConic_Verb: + fuzz->next(&a, &b, &c, &d, &e); + path->conicTo(a, b, c, d, e); + break; + + case SkPath::Verb::kCubic_Verb: + fuzz->next(&a, &b, &c, &d, &e, &f); + path->cubicTo(a, b, c, d, e, f); + break; + + case SkPath::Verb::kClose_Verb: + path->close(); + break; + + case SkPath::Verb::kDone_Verb: + // In this case, simply exit. + return; + } + } +} diff --git a/fuzz/FuzzCommon.h b/fuzz/FuzzCommon.h index c908606be1..bea5a30f86 100644 --- a/fuzz/FuzzCommon.h +++ b/fuzz/FuzzCommon.h @@ -5,12 +5,15 @@ * found in the LICENSE file. */ +#ifndef FuzzCommon_DEFINED +#define FuzzCommon_DEFINED + #include "Fuzz.h" #include "SkPath.h" #include "SkRegion.h" // We don't always want to test NaNs and infinities. -static void fuzz_nice_float(Fuzz* fuzz, float* f) { +static inline void fuzz_nice_float(Fuzz* fuzz, float* f) { float v; fuzz->next(&v); constexpr float kLimit = 1.0e35f; // FLT_MAX? @@ -23,54 +26,6 @@ inline void fuzz_nice_float(Fuzz* fuzz, float* f, Args... rest) { fuzz_nice_float(fuzz, rest...); } -static void fuzz_path(Fuzz* fuzz, SkPath* path, int maxOps) { - if (maxOps < 2) { - maxOps = 2; - } - uint8_t fillType; - fuzz->nextRange(&fillType, 0, (uint8_t)SkPath::kInverseEvenOdd_FillType); - path->setFillType((SkPath::FillType)fillType); - uint8_t numOps; - fuzz->nextRange(&numOps, 2, maxOps); - for (uint8_t i = 0; i < numOps; ++i) { - uint8_t op; - fuzz->nextRange(&op, 0, 6); - SkScalar a, b, c, d, e, f; - switch (op) { - case 0: - fuzz_nice_float(fuzz, &a, &b); - path->moveTo(a, b); - break; - case 1: - fuzz_nice_float(fuzz, &a, &b); - path->lineTo(a, b); - break; - case 2: - fuzz_nice_float(fuzz, &a, &b, &c, &d); - path->quadTo(a, b, c, d); - break; - case 3: - fuzz_nice_float(fuzz, &a, &b, &c, &d, &e); - path->conicTo(a, b, c, d, e); - break; - case 4: - fuzz_nice_float(fuzz, &a, &b, &c, &d, &e, &f); - path->cubicTo(a, b, c, d, e, f); - break; - case 5: - fuzz_nice_float(fuzz, &a, &b, &c, &d, &e); - path->arcTo(a, b, c, d, e); - break; - case 6: - path->close(); - break; - default: - SkASSERT(false); - break; - } - } -} - template <> inline void Fuzz::next(SkRegion* region) { uint8_t N; @@ -86,3 +41,10 @@ inline void Fuzz::next(SkRegion* region) { } } } + +// allows some float values for path points +void FuzzPath(Fuzz* fuzz, SkPath* path, int maxOps); +// allows all float values for path points +void BuildPath(Fuzz* fuzz, SkPath* path, int last_verb); + +#endif diff --git a/fuzz/FuzzPathMeasure.cpp b/fuzz/FuzzPathMeasure.cpp new file mode 100644 index 0000000000..e6933a856f --- /dev/null +++ b/fuzz/FuzzPathMeasure.cpp @@ -0,0 +1,35 @@ +/* + * Copyright 2018 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "Fuzz.h" +#include "FuzzCommon.h" +#include "SkPathMeasure.h" + +void inline ignoreResult(bool ) {} + +DEF_FUZZ(PathMeasure, fuzz) { + uint8_t bits; + fuzz->next(&bits); + SkScalar distance[6]; + for (auto index = 0; index < 6; ++index) { + fuzz->next(&distance[index]); + } + SkPath path; + BuildPath(fuzz, &path, SkPath::Verb::kDone_Verb); + SkRect bounds = path.getBounds(); + SkScalar maxDim = SkTMax(bounds.width(), bounds.height()); + SkScalar resScale = maxDim / 1000; + SkPathMeasure measure(path, bits & 1, resScale); + SkPoint position; + SkVector tangent; + ignoreResult(measure.getPosTan(distance[0], &position, &tangent)); + SkPath dst; + ignoreResult(measure.getSegment(distance[1], distance[2], &dst, (bits >> 1) & 1)); + ignoreResult(measure.nextContour()); + ignoreResult(measure.getPosTan(distance[3], &position, &tangent)); + ignoreResult(measure.getSegment(distance[4], distance[5], &dst, (bits >> 2) & 1)); +} diff --git a/fuzz/FuzzPathop.cpp b/fuzz/FuzzPathop.cpp index f20352436c..18f9e81564 100644 --- a/fuzz/FuzzPathop.cpp +++ b/fuzz/FuzzPathop.cpp @@ -6,58 +6,12 @@ */ #include "Fuzz.h" +#include "FuzzCommon.h" #include "SkPath.h" #include "SkPathOps.h" const int kLastOp = SkPathOp::kReverseDifference_SkPathOp; -void BuildPath(Fuzz* fuzz, - SkPath* path, - int last_verb) { - while (!fuzz->exhausted()) { - // Use a uint8_t to conserve bytes. This makes our "fuzzed bytes footprint" - // smaller, which leads to more efficient fuzzing. - uint8_t operation; - fuzz->next(&operation); - SkScalar a,b,c,d,e,f; - - switch (operation % (last_verb + 1)) { - case SkPath::Verb::kMove_Verb: - fuzz->next(&a, &b); - path->moveTo(a, b); - break; - - case SkPath::Verb::kLine_Verb: - fuzz->next(&a, &b); - path->lineTo(a, b); - break; - - case SkPath::Verb::kQuad_Verb: - fuzz->next(&a, &b, &c, &d); - path->quadTo(a, b, c, d); - break; - - case SkPath::Verb::kConic_Verb: - fuzz->next(&a, &b, &c, &d, &e); - path->conicTo(a, b, c, d, e); - break; - - case SkPath::Verb::kCubic_Verb: - fuzz->next(&a, &b, &c, &d, &e, &f); - path->cubicTo(a, b, c, d, e, f); - break; - - case SkPath::Verb::kClose_Verb: - path->close(); - break; - - case SkPath::Verb::kDone_Verb: - // In this case, simply exit. - return; - } - } -} - DEF_FUZZ(Pathop, fuzz) { SkOpBuilder builder; diff --git a/fuzz/oss_fuzz/FuzzRegionSetPath.cpp b/fuzz/oss_fuzz/FuzzRegionSetPath.cpp index e51a4c03f0..ee6e74759f 100644 --- a/fuzz/oss_fuzz/FuzzRegionSetPath.cpp +++ b/fuzz/oss_fuzz/FuzzRegionSetPath.cpp @@ -14,7 +14,7 @@ void FuzzRegionSetPath(Fuzz* fuzz) { SkPath p; - fuzz_path(fuzz, &p, 1000); + FuzzPath(fuzz, &p, 1000); SkRegion r1; bool initR1; fuzz->next(&initR1); -- cgit v1.2.3