diff options
Diffstat (limited to 'fuzz/FuzzPathop.cpp')
-rw-r--r-- | fuzz/FuzzPathop.cpp | 87 |
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); +} |