Make fuzzers use cleaner interface
signalBoring() no longer exists. When the fuzzer runs out of randomness,
it just returns 0. Fuzzers should not go into infinite loops if this
happens. do while loops are particularly error-prone.
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=3963
Change-Id: Iebcfc14cc6b0a19c5dd015cd39875c81fa44003e
Reviewed-on: https://skia-review.googlesource.com/3963
Commit-Queue: Kevin Lubick <[email protected]>
Reviewed-by: Mike Klein <[email protected]>
diff --git a/fuzz/FilterFuzz.cpp b/fuzz/FilterFuzz.cpp
index 1b9f8a1..81e9bf1 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 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 bool make_bool() {
- return R(2) == 1;
+ return fuzz->next<bool>();
}
static SkRect make_rect() {
@@ -219,30 +220,16 @@
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 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 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 @@
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 @@
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 43918f4..17d75f4 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 @@
// 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;
};
-template <typename T>
-bool Fuzz::next(T* n) {
- if (fNextByte + sizeof(T) > fBytes->size()) {
- return false;
- }
+// 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;
+}
- memcpy(n, fBytes->bytes() + fNextByte, sizeof(T));
+template <typename T>
+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;
+ }
+ 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 6ed4b7c..df36c7c 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 @@
(*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)};
+ 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;
- if (!initGradientParams(fuzz, &colors, &pos, &mode)) {
- return;
- }
+ std::vector<SkColor> colors;
+ std::vector<SkScalar> pos;
+ SkShader::TileMode mode;
+ initGradientParams(fuzz, &colors, &pos, &mode);
- SkPaint p;
- uint32_t flags;
- if (!fuzz->next(&flags)) {
- return;
- }
+ SkPaint p;
+ uint32_t flags = fuzz->next<uint32_t>();
- 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()));
+ 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;
- 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);
+ }
}
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);
-
- 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()));
+ 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>();
- 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);
- }
+ 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::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);
+ 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;
- if (!initGradientParams(fuzz, &colors, &pos, &mode)) {
- return;
- }
+ std::vector<SkColor> colors;
+ std::vector<SkScalar> pos;
+ SkShader::TileMode mode;
+ initGradientParams(fuzz, &colors, &pos, &mode);
- SkPaint p;
- uint32_t flags;
- if (!fuzz->next(&flags)) {
- return;
- }
+ SkPaint p;
+ uint32_t flags = fuzz->next<uint32_t>();
- 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()));
+ 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;
- 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);
+ }
}
void fuzzSweepGradient(Fuzz* fuzz) {
- SkScalar cx, cy;
- bool useLocalMatrix, useGlobalMatrix;
- if (!fuzz->next(&cx) ||
- !fuzz->next(&cy) ||
- !fuzz->next(&useLocalMatrix) ||
- !fuzz->next(&useGlobalMatrix)) {
- return;
- }
+ 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;
- if (!initGradientParams(fuzz, &colors, &pos, &mode)) {
- return;
- }
+ std::vector<SkColor> colors;
+ std::vector<SkScalar> pos;
+ SkShader::TileMode mode;
+ initGradientParams(fuzz, &colors, &pos, &mode);
- 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()));
- }
+ 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 6eb7f3b..1a597d8 100644
--- a/fuzz/FuzzParsePath.cpp
+++ b/fuzz/FuzzParsePath.cpp
@@ -39,48 +39,44 @@
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 @@
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 @@
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 fecf3ca..a555cd6 100644
--- a/fuzz/FuzzPathop.cpp
+++ b/fuzz/FuzzPathop.cpp
@@ -14,51 +14,33 @@
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 @@
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 e7cf78a..dd2ffcc 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 @@
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 00f3349..e6b95fd 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 @@
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;
}