diff options
author | kjlubick <kjlubick@google.com> | 2016-07-19 16:50:03 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-07-19 16:50:03 -0700 |
commit | e565450d0ba81a9869be79664126fd8517dc1632 (patch) | |
tree | 1d8112cd02230a058c477ab071a7e49394b50f2f /fuzz | |
parent | e51c356ae4e074b9c286c50a4efce11205f7463c (diff) |
Port FuzzPathop from chromium
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2148023002
Review-Url: https://codereview.chromium.org/2148023002
Diffstat (limited to 'fuzz')
-rw-r--r-- | fuzz/Fuzz.h | 19 | ||||
-rw-r--r-- | fuzz/FuzzPathop.cpp | 87 | ||||
-rw-r--r-- | fuzz/fuzz.cpp | 8 |
3 files changed, 114 insertions, 0 deletions
diff --git a/fuzz/Fuzz.h b/fuzz/Fuzz.h index 07c2c8456e..79bf675f45 100644 --- a/fuzz/Fuzz.h +++ b/fuzz/Fuzz.h @@ -16,6 +16,14 @@ class Fuzz : SkNoncopyable { public: explicit Fuzz(SkData*); + // Returns the total number of "random" bytes available. + size_t size(); + // Returns the total number of "random" bytes remaining for randomness. + size_t remaining(); + + template <typename T> + bool next(T* n); + bool nextBool(); uint8_t nextB(); uint32_t nextU(); @@ -43,6 +51,17 @@ private: int fNextByte; }; +template <typename T> +bool Fuzz::next(T* n) { + if (fNextByte + sizeof(T) > fBytes->size()) { + return false; + } + + memcpy(n, fBytes->bytes() + fNextByte, sizeof(T)); + fNextByte += sizeof(T); + return true; +} + struct Fuzzable { const char* name; void (*fn)(Fuzz*); diff --git a/fuzz/FuzzPathop.cpp b/fuzz/FuzzPathop.cpp new file mode 100644 index 0000000000..fecf3ca914 --- /dev/null +++ b/fuzz/FuzzPathop.cpp @@ -0,0 +1,87 @@ +/* + * 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.h" +#include "SkPath.h" +#include "SkPathOps.h" + +const int kLastOp = SkPathOp::kReverseDifference_SkPathOp; + +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)) { + + switch (operation % (last_verb + 1)) { + case SkPath::Verb::kMove_Verb: + if (!fuzz->next<SkScalar>(&a) || !fuzz->next<SkScalar>(&b)) + return; + path->moveTo(a, b); + break; + + case SkPath::Verb::kLine_Verb: + if (!fuzz->next<SkScalar>(&a) || !fuzz->next<SkScalar>(&b)) + return; + path->lineTo(a, b); + 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); + 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); + 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); + break; + + case SkPath::Verb::kClose_Verb: + path->close(); + break; + + case SkPath::Verb::kDone_Verb: + // In this case, simply exit. + return; + } + } +} + +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))); + } + + SkPath result; + builder.resolve(&result); +} diff --git a/fuzz/fuzz.cpp b/fuzz/fuzz.cpp index b8375d344a..4ca253343d 100644 --- a/fuzz/fuzz.cpp +++ b/fuzz/fuzz.cpp @@ -14,6 +14,8 @@ #include "SkImageEncoder.h" #include "SkMallocPixelRef.h" #include "SkPicture.h" +#include "SkPicture.h" +#include "SkPicture.h" #include "SkStream.h" #include <cmath> @@ -404,6 +406,12 @@ Fuzz::Fuzz(SkData* bytes) : fBytes(SkSafeRef(bytes)), fNextByte(0) {} void Fuzz::signalBug () { SkDebugf("Signal bug\n"); raise(SIGSEGV); } void Fuzz::signalBoring() { SkDebugf("Signal boring\n"); exit(0); } +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()) { |