123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- /*
- * Copyright 2016 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
- #include "fuzz/Fuzz.h"
- #include "fuzz/FuzzCommon.h"
- #include "include/core/SkPath.h"
- #include "include/core/SkRect.h"
- #include "include/pathops/SkPathOps.h"
- const uint8_t MAX_OPS = 20;
- DEF_FUZZ(Pathop, fuzz) {
- uint8_t choice;
- fuzz->nextRange(&choice, 0, 4);
- switch (choice) {
- case 0: {
- uint8_t ops;
- fuzz->nextRange(&ops, 0, MAX_OPS);
- SkOpBuilder builder;
- for (uint8_t i = 0; i < ops && !fuzz->exhausted(); i++) {
- SkPath path;
- FuzzEvilPath(fuzz, &path, SkPath::Verb::kDone_Verb);
- SkPath::FillType ft;
- fuzz->nextRange(&ft, 0, SkPath::kInverseEvenOdd_FillType);
- path.setFillType(ft);
- SkPathOp op;
- fuzz->nextRange(&op, 0, SkPathOp::kReverseDifference_SkPathOp);
- builder.add(path, op);
- }
- SkPath result;
- builder.resolve(&result);
- break;
- }
- case 1: {
- SkPath path;
- FuzzEvilPath(fuzz, &path, SkPath::Verb::kDone_Verb);
- SkPath::FillType ft;
- fuzz->nextRange(&ft, 0, SkPath::kInverseEvenOdd_FillType);
- path.setFillType(ft);
- SkPath result;
- bool isSame;
- fuzz->next(&isSame);
- if (isSame) {
- result = path;
- }
- Simplify(path, &result);
- break;
- }
- case 2: {
- SkPath path;
- FuzzEvilPath(fuzz, &path, SkPath::Verb::kDone_Verb);
- SkPath::FillType ft;
- fuzz->nextRange(&ft, 0, SkPath::kInverseEvenOdd_FillType);
- path.setFillType(ft);
- SkPath path2;
- FuzzEvilPath(fuzz, &path2, SkPath::Verb::kDone_Verb);
- fuzz->nextRange(&ft, 0, SkPath::kInverseEvenOdd_FillType);
- path.setFillType(ft);
- SkPathOp op;
- fuzz->nextRange(&op, 0, SkPathOp::kReverseDifference_SkPathOp);
- SkPath result;
- uint8_t pickOutput;
- fuzz->nextRange(&pickOutput, 0, 2);
- if (pickOutput == 1) {
- result = path;
- } else if (pickOutput == 2) {
- result = path2;
- }
- Op(path, path2, op, &result);
- break;
- }
- case 3: {
- SkPath path;
- FuzzEvilPath(fuzz, &path, SkPath::Verb::kDone_Verb);
- SkPath::FillType ft;
- fuzz->nextRange(&ft, 0, SkPath::kInverseEvenOdd_FillType);
- path.setFillType(ft);
- SkPath result;
- bool isSame;
- fuzz->next(&isSame);
- if (isSame) {
- result = path;
- }
- AsWinding(path, &result);
- break;
- }
- case 4: {
- SkPath path;
- FuzzEvilPath(fuzz, &path, SkPath::Verb::kDone_Verb);
- SkPath::FillType ft;
- fuzz->nextRange(&ft, 0, SkPath::kInverseEvenOdd_FillType);
- path.setFillType(ft);
- SkRect result;
- TightBounds(path, &result);
- break;
- }
- default: {
- SkASSERT(false);
- break;
- }
- }
- }
- 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);
- }
|