aboutsummaryrefslogtreecommitdiffhomepage
path: root/fuzz
diff options
context:
space:
mode:
Diffstat (limited to 'fuzz')
-rw-r--r--fuzz/Fuzz.h15
-rw-r--r--fuzz/FuzzCanvas.cpp78
-rw-r--r--fuzz/FuzzCommon.h87
-rw-r--r--fuzz/fuzz.cpp41
-rw-r--r--fuzz/oss_fuzz/FuzzRegionDeserialize.cpp39
-rw-r--r--fuzz/oss_fuzz/FuzzRegionSetPath.cpp46
6 files changed, 202 insertions, 104 deletions
diff --git a/fuzz/Fuzz.h b/fuzz/Fuzz.h
index 1a2aa381d0..9dad0595e7 100644
--- a/fuzz/Fuzz.h
+++ b/fuzz/Fuzz.h
@@ -14,15 +14,18 @@
#include "SkTypes.h"
#include <cmath>
+#include <signal.h>
class Fuzz : SkNoncopyable {
public:
- explicit Fuzz(sk_sp<SkData>);
+ explicit Fuzz(sk_sp<SkData> bytes) : fBytes(bytes), fNextByte(0) {}
// Returns the total number of "random" bytes available.
- size_t size();
+ size_t size() { return fBytes->size(); }
// Returns if there are no bytes remaining for fuzzing.
- bool exhausted();
+ bool exhausted(){
+ return fBytes->size() == fNextByte;
+ }
// next() loads fuzzed bytes into the variable passed in by pointer.
// We use this approach instead of T next() because different compilers
@@ -47,7 +50,11 @@ public:
template <typename T>
void nextN(T* ptr, int n);
- void signalBug(); // Tell afl-fuzz these inputs found a bug.
+ void signalBug(){
+ // Tell the fuzzer that these inputs found a bug.
+ SkDebugf("Signal bug\n");
+ raise(SIGSEGV);
+ }
private:
template <typename T>
diff --git a/fuzz/FuzzCanvas.cpp b/fuzz/FuzzCanvas.cpp
index 5bedf9123b..61e51f2157 100644
--- a/fuzz/FuzzCanvas.cpp
+++ b/fuzz/FuzzCanvas.cpp
@@ -6,6 +6,7 @@
*/
#include "Fuzz.h"
+#include "FuzzCommon.h"
// CORE
#include "SkCanvas.h"
@@ -91,83 +92,6 @@ inline T make_fuzz_t(Fuzz* fuzz) {
return t;
}
-// We don't always want to test NaNs and infinities.
-static void fuzz_nice_float(Fuzz* fuzz, float* f) {
- float v;
- fuzz->next(&v);
- constexpr float kLimit = 1.0e35f; // FLT_MAX?
- *f = (v == v && v <= kLimit && v >= -kLimit) ? v : 0.0f;
-}
-
-template <typename... Args>
-inline void fuzz_nice_float(Fuzz* fuzz, float* f, Args... rest) {
- fuzz_nice_float(fuzz, f);
- 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:
- break;
- }
- }
-}
-
-template <>
-inline void Fuzz::next(SkRegion* region) {
- uint8_t N;
- this->nextRange(&N, 0, 10);
- for (uint8_t i = 0; i < N; ++i) {
- SkIRect r;
- uint8_t op;
- this->next(&r);
- r.sort();
- this->nextRange(&op, 0, (uint8_t)SkRegion::kLastOp);
- if (!region->op(r, (SkRegion::Op)op)) {
- return;
- }
- }
-}
-
template <>
inline void Fuzz::next(SkShader::TileMode* m) {
fuzz_enum_range(this, m, 0, SkShader::kTileModeCount - 1);
diff --git a/fuzz/FuzzCommon.h b/fuzz/FuzzCommon.h
new file mode 100644
index 0000000000..a538280c8c
--- /dev/null
+++ b/fuzz/FuzzCommon.h
@@ -0,0 +1,87 @@
+/*
+ * 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 "SkPath.h"
+#include "SkRegion.h"
+
+// We don't always want to test NaNs and infinities.
+static void fuzz_nice_float(Fuzz* fuzz, float* f) {
+ float v;
+ fuzz->next(&v);
+ constexpr float kLimit = 1.0e35f; // FLT_MAX?
+ *f = (v == v && v <= kLimit && v >= -kLimit) ? v : 0.0f;
+}
+
+template <typename... Args>
+inline void fuzz_nice_float(Fuzz* fuzz, float* f, Args... rest) {
+ fuzz_nice_float(fuzz, f);
+ 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:
+ break;
+ }
+ }
+}
+
+template <>
+inline void Fuzz::next(SkRegion* region) {
+ uint8_t N;
+ this->nextRange(&N, 0, 10);
+ for (uint8_t i = 0; i < N; ++i) {
+ SkIRect r;
+ uint8_t op;
+ this->next(&r);
+ r.sort();
+ this->nextRange(&op, 0, (uint8_t)SkRegion::kLastOp);
+ if (!region->op(r, (SkRegion::Op)op)) {
+ return;
+ }
+ }
+}
diff --git a/fuzz/fuzz.cpp b/fuzz/fuzz.cpp
index 45298ca871..c4de6c49f3 100644
--- a/fuzz/fuzz.cpp
+++ b/fuzz/fuzz.cpp
@@ -35,6 +35,7 @@
#include <signal.h>
#include "sk_tool_utils.h"
+
DEFINE_string2(bytes, b, "", "A path to a file or a directory. If a file, the "
"contents will be used as the fuzz bytes. If a directory, all files "
"in the directory will be used as fuzz bytes for the fuzzer, one at a "
@@ -53,6 +54,7 @@ DEFINE_string2(type, t, "", "How to interpret --bytes, one of:\n"
"path_deserialize\n"
"pipe\n"
"region_deserialize\n"
+ "region_set_path\n"
"skp\n"
"sksl2glsl\n"
"textblob");
@@ -67,6 +69,7 @@ static void fuzz_icc(sk_sp<SkData>);
static void fuzz_img(sk_sp<SkData>, uint8_t, uint8_t);
static void fuzz_path_deserialize(sk_sp<SkData>);
static void fuzz_region_deserialize(sk_sp<SkData>);
+static void fuzz_region_set_path(sk_sp<SkData>);
static void fuzz_skp(sk_sp<SkData>);
static void fuzz_skpipe(sk_sp<SkData>);
static void fuzz_textblob_deserialize(sk_sp<SkData>);
@@ -136,6 +139,10 @@ static int fuzz_file(const char* path) {
fuzz_region_deserialize(bytes);
return 0;
}
+ if (0 == strcmp("region_set_path", FLAGS_type[0])) {
+ fuzz_region_set_path(bytes);
+ return 0;
+ }
if (0 == strcmp("pipe", FLAGS_type[0])) {
fuzz_skpipe(bytes);
return 0;
@@ -521,23 +528,13 @@ static void fuzz_path_deserialize(sk_sp<SkData> bytes) {
SkDebugf("[terminated] Success! Initialized SkPath.\n");
}
+bool FuzzRegionDeserialize(sk_sp<SkData> bytes);
+
static void fuzz_region_deserialize(sk_sp<SkData> bytes) {
- SkRegion region;
- if (!region.readFromMemory(bytes->data(), bytes->size())) {
+ if (!FuzzRegionDeserialize(bytes)) {
SkDebugf("[terminated] Couldn't initialize SkRegion.\n");
return;
}
- region.computeRegionComplexity();
- region.isComplex();
- SkRegion r2;
- if (region == r2) {
- region.contains(0,0);
- } else {
- region.contains(1,1);
- }
- auto s = SkSurface::MakeRasterN32Premul(1024, 1024);
- s->getCanvas()->drawRegion(region, SkPaint());
- SkDEBUGCODE(region.validate());
SkDebugf("[terminated] Success! Initialized SkRegion.\n");
}
@@ -554,6 +551,14 @@ static void fuzz_textblob_deserialize(sk_sp<SkData> bytes) {
SkDebugf("[terminated] Success! Initialized SkTextBlob.\n");
}
+void FuzzRegionSetPath(Fuzz* fuzz);
+
+static void fuzz_region_set_path(sk_sp<SkData> bytes) {
+ Fuzz fuzz(bytes);
+ FuzzRegionSetPath(&fuzz);
+ SkDebugf("[terminated] region_set_path didn't crash!\n");
+}
+
static void fuzz_filter_fuzz(sk_sp<SkData> bytes) {
const int BitmapSize = 24;
SkBitmap bitmap;
@@ -603,13 +608,3 @@ static void fuzz_sksl2glsl(sk_sp<SkData> bytes) {
SkDebugf("[terminated] Success! Compiled input.\n");
}
#endif
-
-Fuzz::Fuzz(sk_sp<SkData> bytes) : fBytes(bytes), fNextByte(0) {}
-
-void Fuzz::signalBug() { SkDebugf("Signal bug\n"); raise(SIGSEGV); }
-
-size_t Fuzz::size() { return fBytes->size(); }
-
-bool Fuzz::exhausted() {
- return fBytes->size() == fNextByte;
-}
diff --git a/fuzz/oss_fuzz/FuzzRegionDeserialize.cpp b/fuzz/oss_fuzz/FuzzRegionDeserialize.cpp
new file mode 100644
index 0000000000..c5b37cb68e
--- /dev/null
+++ b/fuzz/oss_fuzz/FuzzRegionDeserialize.cpp
@@ -0,0 +1,39 @@
+/*
+ * 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 "SkCanvas.h"
+#include "SkPaint.h"
+#include "SkRegion.h"
+#include "SkSurface.h"
+
+bool FuzzRegionDeserialize(sk_sp<SkData> bytes) {
+ SkRegion region;
+ if (!region.readFromMemory(bytes->data(), bytes->size())) {
+ return false;
+ }
+ region.computeRegionComplexity();
+ region.isComplex();
+ SkRegion r2;
+ if (region == r2) {
+ region.contains(0,0);
+ } else {
+ region.contains(1,1);
+ }
+ auto s = SkSurface::MakeRasterN32Premul(1024, 1024);
+ s->getCanvas()->drawRegion(region, SkPaint());
+ SkDEBUGCODE(region.validate());
+ return true;
+}
+
+#if defined(IS_FUZZING_WITH_LIBFUZZER)
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+ auto bytes = SkData::MakeWithoutCopy(data, size);
+ FuzzRegionDeserialize(bytes);
+ return 0;
+}
+#endif
diff --git a/fuzz/oss_fuzz/FuzzRegionSetPath.cpp b/fuzz/oss_fuzz/FuzzRegionSetPath.cpp
new file mode 100644
index 0000000000..e51a4c03f0
--- /dev/null
+++ b/fuzz/oss_fuzz/FuzzRegionSetPath.cpp
@@ -0,0 +1,46 @@
+/*
+ * 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 "SkData.h"
+#include "SkPath.h"
+#include "SkRegion.h"
+
+
+void FuzzRegionSetPath(Fuzz* fuzz) {
+ SkPath p;
+ fuzz_path(fuzz, &p, 1000);
+ SkRegion r1;
+ bool initR1;
+ fuzz->next(&initR1);
+ if (initR1) {
+ fuzz->next(&r1);
+ }
+ SkRegion r2;
+ fuzz->next(&r2);
+
+ r1.setPath(p, r2);
+
+ // Do some follow on computations to make sure region is well-formed.
+ r1.computeRegionComplexity();
+ r1.isComplex();
+ if (r1 == r2) {
+ r1.contains(0,0);
+ } else {
+ r1.contains(1,1);
+ }
+}
+
+#if defined(IS_FUZZING_WITH_LIBFUZZER)
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+ sk_sp<SkData> bytes(SkData::MakeWithoutCopy(data, size));
+ Fuzz fuzz(bytes);
+ FuzzRegionSetPath(&fuzz);
+ return 0;
+}
+#endif