aboutsummaryrefslogtreecommitdiffstats
path: root/fuzz/FuzzPathop.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'fuzz/FuzzPathop.cpp')
-rw-r--r--fuzz/FuzzPathop.cpp87
1 files changed, 87 insertions, 0 deletions
diff --git a/fuzz/FuzzPathop.cpp b/fuzz/FuzzPathop.cpp
index fe7b237f5e..7aa229ee8c 100644
--- a/fuzz/FuzzPathop.cpp
+++ b/fuzz/FuzzPathop.cpp
@@ -113,3 +113,90 @@ DEF_FUZZ(Pathop, fuzz) {
}
}
}
+
+
+const int kLastOp = SkPathOp::kReverseDifference_SkPathOp;
+
+void BuildPath(Fuzz* fuzz, SkPath* path) {
+ 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 % (SkPath::Verb::kDone_Verb + 1)) {
+ case SkPath::Verb::kMove_Verb:
+ if (fuzz->remaining() < (2*sizeof(SkScalar))) {
+ fuzz->deplete();
+ return;
+ }
+ fuzz->next(&a, &b);
+ path->moveTo(a, b);
+ break;
+
+ case SkPath::Verb::kLine_Verb:
+ if (fuzz->remaining() < (2*sizeof(SkScalar))) {
+ fuzz->deplete();
+ return;
+ }
+ fuzz->next(&a, &b);
+ path->lineTo(a, b);
+ break;
+
+ case SkPath::Verb::kQuad_Verb:
+ if (fuzz->remaining() < (4*sizeof(SkScalar))) {
+ fuzz->deplete();
+ return;
+ }
+ fuzz->next(&a, &b, &c, &d);
+ path->quadTo(a, b, c, d);
+ break;
+
+ case SkPath::Verb::kConic_Verb:
+ if (fuzz->remaining() < (5*sizeof(SkScalar))) {
+ fuzz->deplete();
+ return;
+ }
+ fuzz->next(&a, &b, &c, &d, &e);
+ path->conicTo(a, b, c, d, e);
+ break;
+
+ case SkPath::Verb::kCubic_Verb:
+ if (fuzz->remaining() < (6*sizeof(SkScalar))) {
+ fuzz->deplete();
+ return;
+ }
+ 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(LegacyChromiumPathop, fuzz) {
+ // See https://cs.chromium.org/chromium/src/testing/libfuzzer/fuzzers/skia_pathop_fuzzer.cc
+ SkOpBuilder builder;
+ while (!fuzz->exhausted()) {
+ SkPath path;
+ uint8_t op;
+ fuzz->next(&op);
+ if (fuzz->exhausted()) {
+ break;
+ }
+
+ BuildPath(fuzz, &path);
+ builder.add(path, static_cast<SkPathOp>(op % (kLastOp + 1)));
+ }
+
+ SkPath result;
+ builder.resolve(&result);
+}