diff options
-rw-r--r-- | BUILD.gn | 3 | ||||
-rw-r--r-- | fuzz/FilterFuzz.cpp | 38 | ||||
-rw-r--r-- | fuzz/Fuzz.h | 98 | ||||
-rw-r--r-- | fuzz/FuzzGradients.cpp | 351 | ||||
-rw-r--r-- | fuzz/FuzzParsePath.cpp | 42 | ||||
-rw-r--r-- | fuzz/FuzzPathop.cpp | 53 | ||||
-rw-r--r-- | fuzz/FuzzScaleToSides.cpp | 10 | ||||
-rw-r--r-- | fuzz/fuzz.cpp | 57 |
8 files changed, 252 insertions, 400 deletions
@@ -1139,9 +1139,6 @@ if (skia_enable_tools) { } executable("fuzz") { - if (is_skia_standalone) { - configs -= [ "//gn:no_exceptions" ] - } sources = [ "fuzz/FilterFuzz.cpp", "fuzz/FuzzGradients.cpp", diff --git a/fuzz/FilterFuzz.cpp b/fuzz/FilterFuzz.cpp index 1b9f8a14b3..81e9bf1f15 100644 --- a/fuzz/FilterFuzz.cpp +++ b/fuzz/FilterFuzz.cpp @@ -44,6 +44,7 @@ #include "SkTileImageFilter.h" #include "SkTypeface.h" #include "SkXfermodeImageFilter.h" +#include <cmath> #include <stdio.h> #include <time.h> @@ -55,8 +56,8 @@ static const int kBitmapSize = 24; static bool return_large = false; static bool return_undef = false; -static int R(float x) { - return (int)floor(SkScalarToFloat(fuzz->nextF1()) * x); +static int R(int x) { + return abs(fuzz->next<int>()) % x; } #if defined _WIN32 @@ -130,7 +131,7 @@ static SkString make_font_name() { } static bool make_bool() { - return R(2) == 1; + return fuzz->next<bool>(); } static SkRect make_rect() { @@ -219,30 +220,16 @@ static SkDisplacementMapEffect::ChannelSelectorType make_channel_selector_type() return static_cast<SkDisplacementMapEffect::ChannelSelectorType>(R(4)+1); } -static bool valid_for_raster_canvas(const SkImageInfo& info) { - switch (info.colorType()) { - case kAlpha_8_SkColorType: - case kRGB_565_SkColorType: - return true; - case kN32_SkColorType: - return kPremul_SkAlphaType == info.alphaType() || - kOpaque_SkAlphaType == info.alphaType(); - default: - break; - } - return false; -} - static SkColorType rand_colortype() { return (SkColorType)R(kLastEnum_SkColorType + 1); } static void rand_bitmap_for_canvas(SkBitmap* bitmap) { - SkImageInfo info; - do { - info = SkImageInfo::Make(kBitmapSize, kBitmapSize, rand_colortype(), + SkImageInfo info = SkImageInfo::Make(kBitmapSize, kBitmapSize, rand_colortype(), kPremul_SkAlphaType); - } while (!valid_for_raster_canvas(info) || !bitmap->tryAllocPixels(info)); + if (!bitmap->tryAllocPixels(info)){ + SkDebugf("Bitmap not allocated\n"); + } } static void make_g_bitmap(SkBitmap& bitmap) { @@ -413,7 +400,7 @@ static SkPath make_path() { static sk_sp<SkPathEffect> make_path_effect(bool canBeNull = true) { sk_sp<SkPathEffect> pathEffect; - if (canBeNull && (R(3) == 1)) { return pathEffect; } + if (canBeNull && (R(3) == 0)) { return pathEffect; } switch (R(9)) { case 0: @@ -484,6 +471,9 @@ static sk_sp<SkImageFilter> make_image_filter(bool canBeNull = true); static SkPaint make_paint() { SkPaint paint; + if (fuzz->exhausted()) { + return paint; + } paint.setHinting(make_paint_hinting()); paint.setAntiAlias(make_bool()); paint.setDither(make_bool()); @@ -535,7 +525,7 @@ static sk_sp<SkImageFilter> make_image_filter(bool canBeNull) { sk_sp<SkImageFilter> filter; // Add a 1 in 3 chance to get a nullptr input - if (canBeNull && (R(3) == 1)) { + if (fuzz->exhausted() || (canBeNull && R(3) == 1)) { return filter; } @@ -729,7 +719,7 @@ static sk_sp<SkImageFilter> make_image_filter(bool canBeNull) { default: break; } - return (filter || canBeNull) ? filter : make_image_filter(canBeNull); + return filter; } static sk_sp<SkImageFilter> make_serialized_image_filter() { diff --git a/fuzz/Fuzz.h b/fuzz/Fuzz.h index 43918f4a94..17d75f4d34 100644 --- a/fuzz/Fuzz.h +++ b/fuzz/Fuzz.h @@ -12,7 +12,7 @@ #include "SkTRegistry.h" #include "SkTypes.h" -#include <vector> +#include <cmath> class Fuzz : SkNoncopyable { public: @@ -20,60 +20,78 @@ public: // Returns the total number of "random" bytes available. size_t size(); - // Returns the total number of "random" bytes remaining for randomness. - size_t remaining(); + // Returns if there are no bytes remaining for fuzzing. + bool exhausted(); template <typename T> - bool SK_WARN_UNUSED_RESULT next(T* n); + T next(); - // UBSAN reminds us that bool can only legally hold 0 or 1. - bool SK_WARN_UNUSED_RESULT next(bool* b) { - uint8_t byte; - if (!this->next(&byte)) { - return false; - } - *b = (byte & 1) == 1; - return true; - } + // nextRange returns values only in [min, max]. + template <typename T> + T nextRange(T min, T max); - // The nextFoo methods are deprecated. - // TODO(kjlubick): replace existing uses with next() and remove these. - bool nextBool(); - uint8_t nextB(); - uint32_t nextU(); - // This can be nan, +- infinity, 0, anything. - float nextF(); - // Returns a float between [0..1) as a IEEE float - float nextF1(); - - // Return the next fuzzed value [min, max) as an unsigned 32bit integer. - uint32_t nextRangeU(uint32_t min, uint32_t max); - /** - * Returns next fuzzed value [min...max) as a float. - * Will not be Infinity or NaN. - */ - float nextRangeF(float min, float max); - - void signalBug (); // Tell afl-fuzz these inputs found a bug. - void signalBoring(); // Tell afl-fuzz these inputs are not worth testing. + void signalBug(); // Tell afl-fuzz these inputs found a bug. private: template <typename T> T nextT(); sk_sp<SkData> fBytes; - int fNextByte; + size_t fNextByte; }; +// UBSAN reminds us that bool can only legally hold 0 or 1. +template <> +inline bool Fuzz::next<bool>() { + return (this->next<uint8_t>() & 1) == 1; +} + template <typename T> -bool Fuzz::next(T* n) { - if (fNextByte + sizeof(T) > fBytes->size()) { - return false; +T Fuzz::next() { + if ((fNextByte + sizeof(T)) > fBytes->size()) { + T n = 0; + memcpy(&n, fBytes->bytes() + fNextByte, fBytes->size() - fNextByte); + fNextByte = fBytes->size(); + return n; } - - memcpy(n, fBytes->bytes() + fNextByte, sizeof(T)); + T n; + memcpy(&n, fBytes->bytes() + fNextByte, sizeof(T)); fNextByte += sizeof(T); - return true; + return n; +} + +template <> +inline float Fuzz::nextRange(float min, float max) { + if (min > max) { + SkDebugf("Check mins and maxes (%f, %f)\n", min, max); + this->signalBug(); + } + float f = this->next<float>(); + if (!std::isnormal(f) && f != 0.0f) { + // Don't deal with infinity or other strange floats. + return max; + } + return min + std::fmod(std::abs(f), (max - min + 1)); +} + +template <typename T> +T Fuzz::nextRange(T min, T max) { + if (min > max) { + SkDebugf("Check mins and maxes (%d, %d)\n", min, max); + this->signalBug(); + } + T n = this->next<T>(); + T range = max - min + 1; + if (0 == range) { + return n; + } else { + n = abs(n); + if (n < 0) { + // abs(INT_MIN) = INT_MIN, so we check this to avoid accidental negatives. + return min; + } + return min + n % range; + } } struct Fuzzable { diff --git a/fuzz/FuzzGradients.cpp b/fuzz/FuzzGradients.cpp index 6ed4b7cb7a..df36c7ce8f 100644 --- a/fuzz/FuzzGradients.cpp +++ b/fuzz/FuzzGradients.cpp @@ -12,48 +12,27 @@ #include "SkTLazy.h" #include <algorithm> +#include <vector> const int MAX_COUNT = 400; -bool makeMatrix(Fuzz* fuzz, SkMatrix* m) { - SkScalar scaleX, skewX, transX, skewY, scaleY, transY, persp0, persp1, persp2; - if (!fuzz->next(&scaleX) || - !fuzz->next(&skewX) || - !fuzz->next(&transX) || - !fuzz->next(&skewY) || - !fuzz->next(&scaleY) || - !fuzz->next(&transY) || - !fuzz->next(&persp0) || - !fuzz->next(&persp1) || - !fuzz->next(&persp2)) { - return false; - } - m->setAll(scaleX, skewX, transX, skewY, scaleY, transY, persp0, persp1, persp2); - return true; +void makeMatrix(Fuzz* fuzz, SkMatrix* m) { + m->setAll(fuzz->next<SkScalar>(), fuzz->next<SkScalar>(), fuzz->next<SkScalar>(), + fuzz->next<SkScalar>(), fuzz->next<SkScalar>(), fuzz->next<SkScalar>(), + fuzz->next<SkScalar>(), fuzz->next<SkScalar>(), fuzz->next<SkScalar>()); } -bool initGradientParams(Fuzz* fuzz, std::vector<SkColor>* colors, - std::vector<SkScalar>* pos, SkShader::TileMode* mode) { - if (fuzz->remaining() < sizeof(uint32_t)) { - return false; - } - uint32_t count = fuzz->nextRangeU(0, MAX_COUNT); +void initGradientParams(Fuzz* fuzz, std::vector<SkColor>* colors, + std::vector<SkScalar>* pos, SkShader::TileMode* mode) { + int count = fuzz->nextRange(0, MAX_COUNT); - if (fuzz->remaining() < sizeof(uint32_t)) { - return false; - } - *mode = static_cast<SkShader::TileMode>(fuzz->nextRangeU(0, 3)); + *mode = static_cast<SkShader::TileMode>(fuzz->nextRange(0, 2)); colors->clear(); pos ->clear(); - for (uint32_t i = 0; i < count; i++) { - SkColor c; - SkScalar s; - if (!fuzz->next(&c) || !fuzz->next(&s)) { - return false; - } - colors->push_back(c); - pos ->push_back(s); + for (int i = 0; i < count; i++) { + colors->push_back(fuzz->next<SkColor>()); + pos ->push_back(fuzz->next<SkScalar>()); } if (count) { std::sort(pos->begin(), pos->end()); @@ -61,208 +40,150 @@ bool initGradientParams(Fuzz* fuzz, std::vector<SkColor>* colors, (*pos)[count - 1] = 1; (*pos)[0] = 0; } - return true; } void fuzzLinearGradient(Fuzz* fuzz) { - SkScalar a, b, c, d; - bool useLocalMatrix, useGlobalMatrix; - if (!fuzz->next(&a) || - !fuzz->next(&b) || - !fuzz->next(&c) || - !fuzz->next(&d) || - !fuzz->next(&useLocalMatrix) || - !fuzz->next(&useGlobalMatrix)) { - return; - } - SkPoint pts[2] = {SkPoint::Make(a,b), SkPoint::Make(c, d)}; - - std::vector<SkColor> colors; - std::vector<SkScalar> pos; - SkShader::TileMode mode; - if (!initGradientParams(fuzz, &colors, &pos, &mode)) { - return; - } - - SkPaint p; - uint32_t flags; - if (!fuzz->next(&flags)) { - return; - } - - SkTLazy<SkMatrix> localMatrix; - if (useLocalMatrix && !makeMatrix(fuzz, localMatrix.init())) { - return; - } - p.setShader(SkGradientShader::MakeLinear(pts, colors.data(), pos.data(), - colors.size(), mode, flags, localMatrix.getMaybeNull())); - - sk_sp<SkSurface> surface(SkSurface::MakeRasterN32Premul(50, 50)); - if (useGlobalMatrix) { - SkMatrix gm; - if (!makeMatrix(fuzz, &gm)) { - return; - } - SkCanvas* c = surface->getCanvas(); - c->setMatrix(gm); - c->drawPaint(p); - } else { - surface->getCanvas()->drawPaint(p); - } + SkPoint pts[2] = {SkPoint::Make(fuzz->next<SkScalar>(), fuzz->next<SkScalar>()), + SkPoint::Make(fuzz->next<SkScalar>(), fuzz->next<SkScalar>())}; + bool useLocalMatrix = fuzz->next<bool>(); + bool useGlobalMatrix = fuzz->next<bool>(); + + std::vector<SkColor> colors; + std::vector<SkScalar> pos; + SkShader::TileMode mode; + initGradientParams(fuzz, &colors, &pos, &mode); + + SkPaint p; + uint32_t flags = fuzz->next<uint32_t>(); + + SkTLazy<SkMatrix> localMatrix; + if (useLocalMatrix) { + makeMatrix(fuzz, localMatrix.init()); + } + p.setShader(SkGradientShader::MakeLinear(pts, colors.data(), pos.data(), + colors.size(), mode, flags, localMatrix.getMaybeNull())); + + sk_sp<SkSurface> surface(SkSurface::MakeRasterN32Premul(50, 50)); + if (useGlobalMatrix) { + SkMatrix gm; + makeMatrix(fuzz, &gm); + SkCanvas* c = surface->getCanvas(); + c->setMatrix(gm); + c->drawPaint(p); + } else { + surface->getCanvas()->drawPaint(p); + } } void fuzzRadialGradient(Fuzz* fuzz) { - SkScalar a, b, radius; - bool useLocalMatrix, useGlobalMatrix; - if (!fuzz->next(&a) || - !fuzz->next(&b) || - !fuzz->next(&radius) || - !fuzz->next(&useLocalMatrix) || - !fuzz->next(&useGlobalMatrix)) { - return; - } - SkPoint center = SkPoint::Make(a,b); + SkPoint center = SkPoint::Make(fuzz->next<SkScalar>(), fuzz->next<SkScalar>()); + SkScalar radius = fuzz->next<SkScalar>(); + bool useLocalMatrix = fuzz->next<bool>(); + bool useGlobalMatrix = fuzz->next<bool>(); - std::vector<SkColor> colors; - std::vector<SkScalar> pos; - SkShader::TileMode mode; - if (!initGradientParams(fuzz, &colors, &pos, &mode)) { - return; - } - SkPaint p; - uint32_t flags; - if (!fuzz->next(&flags)) { - return; - } - - SkTLazy<SkMatrix> localMatrix; - if (useLocalMatrix && !makeMatrix(fuzz, localMatrix.init())) { - return; - } - p.setShader(SkGradientShader::MakeRadial(center, radius, colors.data(), - pos.data(), colors.size(), mode, flags, localMatrix.getMaybeNull())); + std::vector<SkColor> colors; + std::vector<SkScalar> pos; + SkShader::TileMode mode; + initGradientParams(fuzz, &colors, &pos, &mode); + SkPaint p; + uint32_t flags = fuzz->next<uint32_t>(); - sk_sp<SkSurface> surface(SkSurface::MakeRasterN32Premul(50, 50)); - if (useGlobalMatrix) { - SkMatrix gm; - if (!makeMatrix(fuzz, &gm)) { - return; - } - SkCanvas* c = surface->getCanvas(); - c->setMatrix(gm); - c->drawPaint(p); - } else { - surface->getCanvas()->drawPaint(p); - } + SkTLazy<SkMatrix> localMatrix; + if (useLocalMatrix) { + makeMatrix(fuzz, localMatrix.init()); + } + p.setShader(SkGradientShader::MakeRadial(center, radius, colors.data(), + pos.data(), colors.size(), mode, flags, localMatrix.getMaybeNull())); + + + sk_sp<SkSurface> surface(SkSurface::MakeRasterN32Premul(50, 50)); + if (useGlobalMatrix) { + SkMatrix gm; + makeMatrix(fuzz, &gm); + SkCanvas* c = surface->getCanvas(); + c->setMatrix(gm); + c->drawPaint(p); + } else { + surface->getCanvas()->drawPaint(p); + } } void fuzzTwoPointConicalGradient(Fuzz* fuzz) { - SkScalar a, b, startRadius, c, d, endRadius; - bool useLocalMatrix, useGlobalMatrix; - if (!fuzz->next(&a) || - !fuzz->next(&b) || - !fuzz->next(&startRadius) || - !fuzz->next(&c) || - !fuzz->next(&d) || - !fuzz->next(&endRadius) || - !fuzz->next(&useLocalMatrix) || - !fuzz->next(&useGlobalMatrix)) { - return; - } - SkPoint start = SkPoint::Make(a, b); - SkPoint end = SkPoint::Make(c, d); - - std::vector<SkColor> colors; - std::vector<SkScalar> pos; - SkShader::TileMode mode; - if (!initGradientParams(fuzz, &colors, &pos, &mode)) { - return; - } - - SkPaint p; - uint32_t flags; - if (!fuzz->next(&flags)) { - return; - } - - SkTLazy<SkMatrix> localMatrix; - if (useLocalMatrix && !makeMatrix(fuzz, localMatrix.init())) { - return; - } - p.setShader(SkGradientShader::MakeTwoPointConical(start, startRadius, - end, endRadius, colors.data(), pos.data(), colors.size(), mode, - flags, localMatrix.getMaybeNull())); - - sk_sp<SkSurface> surface(SkSurface::MakeRasterN32Premul(50, 50)); - if (useGlobalMatrix) { - SkMatrix gm; - if (!makeMatrix(fuzz, &gm)) { - return; - } - SkCanvas* c = surface->getCanvas(); - c->setMatrix(gm); - c->drawPaint(p); - } else { - surface->getCanvas()->drawPaint(p); - } + SkPoint start = SkPoint::Make(fuzz->next<SkScalar>(), fuzz->next<SkScalar>()); + SkPoint end = SkPoint::Make(fuzz->next<SkScalar>(), fuzz->next<SkScalar>()); + SkScalar startRadius = fuzz->next<SkScalar>(); + SkScalar endRadius = fuzz->next<SkScalar>(); + bool useLocalMatrix = fuzz->next<bool>(); + bool useGlobalMatrix = fuzz->next<bool>(); + + std::vector<SkColor> colors; + std::vector<SkScalar> pos; + SkShader::TileMode mode; + initGradientParams(fuzz, &colors, &pos, &mode); + + SkPaint p; + uint32_t flags = fuzz->next<uint32_t>(); + + SkTLazy<SkMatrix> localMatrix; + if (useLocalMatrix) { + makeMatrix(fuzz, localMatrix.init()); + } + p.setShader(SkGradientShader::MakeTwoPointConical(start, startRadius, + end, endRadius, colors.data(), pos.data(), colors.size(), mode, + flags, localMatrix.getMaybeNull())); + + sk_sp<SkSurface> surface(SkSurface::MakeRasterN32Premul(50, 50)); + if (useGlobalMatrix) { + SkMatrix gm; + makeMatrix(fuzz, &gm); + SkCanvas* c = surface->getCanvas(); + c->setMatrix(gm); + c->drawPaint(p); + } else { + surface->getCanvas()->drawPaint(p); + } } void fuzzSweepGradient(Fuzz* fuzz) { - SkScalar cx, cy; - bool useLocalMatrix, useGlobalMatrix; - if (!fuzz->next(&cx) || - !fuzz->next(&cy) || - !fuzz->next(&useLocalMatrix) || - !fuzz->next(&useGlobalMatrix)) { - return; - } - - std::vector<SkColor> colors; - std::vector<SkScalar> pos; - SkShader::TileMode mode; - if (!initGradientParams(fuzz, &colors, &pos, &mode)) { - return; - } - - SkPaint p; - if (useLocalMatrix) { - SkMatrix m; - if (!makeMatrix(fuzz, &m)) { - return; - } - uint32_t flags; - if (!fuzz->next(&flags)) { - return; - } - p.setShader(SkGradientShader::MakeSweep(cx, cy, colors.data(), - pos.data(), colors.size(), flags, &m)); - } else { - p.setShader(SkGradientShader::MakeSweep(cx, cy, colors.data(), - pos.data(), colors.size())); - } - + SkScalar cx = fuzz->next<SkScalar>(); + SkScalar cy = fuzz->next<SkScalar>(); + bool useLocalMatrix = fuzz->next<bool>(); + bool useGlobalMatrix = fuzz->next<bool>(); + + std::vector<SkColor> colors; + std::vector<SkScalar> pos; + SkShader::TileMode mode; + initGradientParams(fuzz, &colors, &pos, &mode); + + SkPaint p; + if (useLocalMatrix) { + SkMatrix m; + makeMatrix(fuzz, &m); + uint32_t flags = fuzz->next<uint32_t>(); + + p.setShader(SkGradientShader::MakeSweep(cx, cy, colors.data(), + pos.data(), colors.size(), flags, &m)); + } else { + p.setShader(SkGradientShader::MakeSweep(cx, cy, colors.data(), + pos.data(), colors.size())); + } - sk_sp<SkSurface> surface(SkSurface::MakeRasterN32Premul(50, 50)); - if (useGlobalMatrix) { - SkMatrix gm; - if (!makeMatrix(fuzz, &gm)) { - return; - } - SkCanvas* c = surface->getCanvas(); - c->setMatrix(gm); - c->drawPaint(p); - } else { - surface->getCanvas()->drawPaint(p); - } + sk_sp<SkSurface> surface(SkSurface::MakeRasterN32Premul(50, 50)); + if (useGlobalMatrix) { + SkMatrix gm; + makeMatrix(fuzz, &gm); + SkCanvas* c = surface->getCanvas(); + c->setMatrix(gm); + c->drawPaint(p); + } else { + surface->getCanvas()->drawPaint(p); + } } DEF_FUZZ(Gradients, fuzz) { - uint8_t i; - if (!fuzz->next(&i)) { - return; - } + uint8_t i = fuzz->next<uint8_t>(); switch(i) { case 0: diff --git a/fuzz/FuzzParsePath.cpp b/fuzz/FuzzParsePath.cpp index 6eb7f3b713..1a597d87a0 100644 --- a/fuzz/FuzzParsePath.cpp +++ b/fuzz/FuzzParsePath.cpp @@ -39,48 +39,44 @@ static void add_white(Fuzz* fuzz, SkString* atom) { atom->append(" "); return; } - int reps = fuzz->nextRangeU(0, 2); + int reps = fuzz->nextRange(0, 2); for (int rep = 0; rep < reps; ++rep) { - int index = fuzz->nextRangeU(0, (int) SK_ARRAY_COUNT(gWhiteSpace) - 1); + int index = fuzz->nextRange(0, (int) SK_ARRAY_COUNT(gWhiteSpace) - 1); if (gWhiteSpace[index]) { atom->append(&gWhiteSpace[index], 1); } } } +static void add_some_white(Fuzz* fuzz, SkString* atom) { + for(int i = 0; i < 10; i++) { + add_white(fuzz, atom); + } +} + static void add_comma(Fuzz* fuzz, SkString* atom) { if (gEasy) { atom->append(","); return; } - size_t count = atom->size(); add_white(fuzz, atom); - if (fuzz->nextBool()) { + if (fuzz->next<bool>()) { atom->append(","); } - do { - add_white(fuzz, atom); - } while (count == atom->size()); -} - -static void add_some_white(Fuzz* fuzz, SkString* atom) { - size_t count = atom->size(); - do { - add_white(fuzz, atom); - } while (count == atom->size()); + add_some_white(fuzz, atom); } SkString MakeRandomParsePathPiece(Fuzz* fuzz) { SkString atom; - int index = fuzz->nextRangeU(0, (int) SK_ARRAY_COUNT(gLegal) - 1); + int index = fuzz->nextRange(0, (int) SK_ARRAY_COUNT(gLegal) - 1); const Legal& legal = gLegal[index]; gEasy ? atom.append("\n") : add_white(fuzz, &atom); - char symbol = legal.fSymbol | (fuzz->nextBool() ? 0x20 : 0); + char symbol = legal.fSymbol | (fuzz->next<bool>() ? 0x20 : 0); atom.append(&symbol, 1); - int reps = fuzz->nextRangeU(1, 3); + int reps = fuzz->nextRange(1, 3); for (int rep = 0; rep < reps; ++rep) { for (int index = 0; index < legal.fScalars; ++index) { - SkScalar coord = fuzz->nextRangeF(0, 100); + SkScalar coord = fuzz->nextRange(0.0f, 100.0f); add_white(fuzz, &atom); atom.appendScalar(coord); if (rep < reps - 1 && index < legal.fScalars - 1) { @@ -89,11 +85,11 @@ SkString MakeRandomParsePathPiece(Fuzz* fuzz) { add_some_white(fuzz, &atom); } if ('A' == legal.fSymbol && 1 == index) { - atom.appendScalar(fuzz->nextRangeF(-720, 720)); + atom.appendScalar(fuzz->nextRange(-720.0f, 720.0f)); add_comma(fuzz, &atom); - atom.appendU32(fuzz->nextRangeU(0, 1)); + atom.appendU32(fuzz->nextRange(0, 1)); add_comma(fuzz, &atom); - atom.appendU32(fuzz->nextRangeU(0, 1)); + atom.appendU32(fuzz->nextRange(0, 1)); add_comma(fuzz, &atom); } } @@ -104,12 +100,12 @@ SkString MakeRandomParsePathPiece(Fuzz* fuzz) { DEF_FUZZ(ParsePath, fuzz) { SkPath path; SkString spec; - uint32_t count = fuzz->nextRangeU(0, 40); + uint32_t count = fuzz->nextRange(0, 40); for (uint32_t i = 0; i < count; ++i) { spec.append(MakeRandomParsePathPiece(fuzz)); } SkDebugf("SkParsePath::FromSVGString(%s, &path);\n",spec.c_str()); if (!SkParsePath::FromSVGString(spec.c_str(), &path)){ - fuzz->signalBug(); + SkDebugf("Could not decode path\n"); } } diff --git a/fuzz/FuzzPathop.cpp b/fuzz/FuzzPathop.cpp index fecf3ca914..a555cd6344 100644 --- a/fuzz/FuzzPathop.cpp +++ b/fuzz/FuzzPathop.cpp @@ -14,51 +14,33 @@ const int kLastOp = SkPathOp::kReverseDifference_SkPathOp; void BuildPath(Fuzz* fuzz, SkPath* path, int last_verb) { - uint8_t operation; - SkScalar a, b, c, d, e, f; - while (fuzz->next<uint8_t>(&operation)) { + while (!fuzz->exhausted()) { + uint8_t operation = fuzz->next<uint8_t>(); switch (operation % (last_verb + 1)) { case SkPath::Verb::kMove_Verb: - if (!fuzz->next<SkScalar>(&a) || !fuzz->next<SkScalar>(&b)) - return; - path->moveTo(a, b); + path->moveTo(fuzz->next<SkScalar>(), fuzz->next<SkScalar>()); break; case SkPath::Verb::kLine_Verb: - if (!fuzz->next<SkScalar>(&a) || !fuzz->next<SkScalar>(&b)) - return; - path->lineTo(a, b); + path->lineTo(fuzz->next<SkScalar>(), fuzz->next<SkScalar>()); break; case SkPath::Verb::kQuad_Verb: - if (!fuzz->next<SkScalar>(&a) || - !fuzz->next<SkScalar>(&b) || - !fuzz->next<SkScalar>(&c) || - !fuzz->next<SkScalar>(&d)) - return; - path->quadTo(a, b, c, d); + path->quadTo(fuzz->next<SkScalar>(), fuzz->next<SkScalar>(), + fuzz->next<SkScalar>(), fuzz->next<SkScalar>()); break; case SkPath::Verb::kConic_Verb: - if (!fuzz->next<SkScalar>(&a) || - !fuzz->next<SkScalar>(&b) || - !fuzz->next<SkScalar>(&c) || - !fuzz->next<SkScalar>(&d) || - !fuzz->next<SkScalar>(&e)) - return; - path->conicTo(a, b, c, d, e); + path->conicTo(fuzz->next<SkScalar>(), fuzz->next<SkScalar>(), + fuzz->next<SkScalar>(), fuzz->next<SkScalar>(), + fuzz->next<SkScalar>()); break; case SkPath::Verb::kCubic_Verb: - if (!fuzz->next<SkScalar>(&a) || - !fuzz->next<SkScalar>(&b) || - !fuzz->next<SkScalar>(&c) || - !fuzz->next<SkScalar>(&d) || - !fuzz->next<SkScalar>(&e) || - !fuzz->next<SkScalar>(&f)) - return; - path->cubicTo(a, b, c, d, e, f); + path->cubicTo(fuzz->next<SkScalar>(), fuzz->next<SkScalar>(), + fuzz->next<SkScalar>(), fuzz->next<SkScalar>(), + fuzz->next<SkScalar>(), fuzz->next<SkScalar>()); break; case SkPath::Verb::kClose_Verb: @@ -74,13 +56,12 @@ void BuildPath(Fuzz* fuzz, DEF_FUZZ(Pathop, fuzz) { SkOpBuilder builder; - while (fuzz->remaining() >= sizeof(uint8_t)) { - SkPath path; - uint8_t op = fuzz->nextB(); - BuildPath(fuzz, &path, SkPath::Verb::kDone_Verb); - builder.add(path, static_cast<SkPathOp>(op % (kLastOp + 1))); - } + uint8_t stragglerOp = fuzz->next<uint8_t>(); + SkPath path; + + BuildPath(fuzz, &path, SkPath::Verb::kDone_Verb); + builder.add(path, static_cast<SkPathOp>(stragglerOp % (kLastOp + 1))); SkPath result; builder.resolve(&result); diff --git a/fuzz/FuzzScaleToSides.cpp b/fuzz/FuzzScaleToSides.cpp index e7cf78a4b8..dd2ffcca88 100644 --- a/fuzz/FuzzScaleToSides.cpp +++ b/fuzz/FuzzScaleToSides.cpp @@ -16,9 +16,9 @@ #include <cmath> DEF_FUZZ(ScaleToSides, fuzz) { - float radius1 = fuzz->nextF(), - radius2 = fuzz->nextF(), - width = fuzz->nextF(); + float radius1 = fuzz->next<float>(), + radius2 = fuzz->next<float>(), + width = fuzz->next<float>(); if (!std::isfinite(radius1) || !std::isfinite(radius2) || @@ -27,12 +27,12 @@ DEF_FUZZ(ScaleToSides, fuzz) { radius2 <= 0.0f || width <= 0.0f) { - fuzz->signalBoring(); + return; } double scale = (double)width / ((double)radius1 + (double)radius2); if (scale >= 1.0 || scale <= 0.0) { - fuzz->signalBoring(); + return; } SkDebugf("%g %g %g %g\n", radius1, radius2, width, scale); SkScaleToSides::AdjustRadii(width, scale, &radius1, &radius2); diff --git a/fuzz/fuzz.cpp b/fuzz/fuzz.cpp index 00f3349be4..e6b95fd066 100644 --- a/fuzz/fuzz.cpp +++ b/fuzz/fuzz.cpp @@ -19,9 +19,7 @@ #include "SkSLCompiler.h" #include "SkStream.h" -#include <cmath> #include <signal.h> -#include <stdlib.h> DEFINE_string2(bytes, b, "", "A path to a file. This can be the fuzz bytes or a binary to parse."); DEFINE_string2(name, n, "", "If --type is 'api', fuzz the API with this name."); @@ -411,59 +409,10 @@ int fuzz_sksl2glsl(sk_sp<SkData> bytes) { Fuzz::Fuzz(sk_sp<SkData> bytes) : fBytes(bytes), fNextByte(0) {} -void Fuzz::signalBug () { SkDebugf("Signal bug\n"); raise(SIGSEGV); } -void Fuzz::signalBoring() { SkDebugf("Signal boring\n"); exit(0); } +void Fuzz::signalBug() { SkDebugf("Signal bug\n"); raise(SIGSEGV); } size_t Fuzz::size() { return fBytes->size(); } -size_t Fuzz::remaining() { - return fBytes->size() - fNextByte; -} - -template <typename T> -T Fuzz::nextT() { - if (fNextByte + sizeof(T) > fBytes->size()) { - this->signalBoring(); - } - - T val; - memcpy(&val, fBytes->bytes() + fNextByte, sizeof(T)); - fNextByte += sizeof(T); - return val; -} - -uint8_t Fuzz::nextB() { return this->nextT<uint8_t >(); } -bool Fuzz::nextBool() { return nextB()&1; } -uint32_t Fuzz::nextU() { return this->nextT<uint32_t>(); } -float Fuzz::nextF() { return this->nextT<float >(); } - -float Fuzz::nextF1() { - // This is the same code as is in SkRandom's nextF() - unsigned int floatint = 0x3f800000 | (this->nextU() >> 9); - float f = SkBits2Float(floatint) - 1.0f; - return f; -} - -uint32_t Fuzz::nextRangeU(uint32_t min, uint32_t max) { - if (min > max) { - SkDebugf("Check mins and maxes (%d, %d)\n", min, max); - this->signalBoring(); - } - uint32_t range = max - min + 1; - if (0 == range) { - return this->nextU(); - } else { - return min + this->nextU() % range; - } -} -float Fuzz::nextRangeF(float min, float max) { - if (min > max) { - SkDebugf("Check mins and maxes (%f, %f)\n", min, max); - this->signalBoring(); - } - float f = std::abs(this->nextF()); - if (!std::isnormal(f) && f != 0.0) { - this->signalBoring(); - } - return min + fmod(f, (max - min + 1)); +bool Fuzz::exhausted() { + return fBytes->size() == fNextByte; } |