Port FuzzPathop from chromium

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2148023002

Review-Url: https://codereview.chromium.org/2148023002
This commit is contained in:
kjlubick 2016-07-19 16:50:03 -07:00 committed by Commit bot
parent e51c356ae4
commit e565450d0b
3 changed files with 114 additions and 0 deletions

View File

@ -16,6 +16,14 @@ class Fuzz : SkNoncopyable {
public: public:
explicit Fuzz(SkData*); 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(); bool nextBool();
uint8_t nextB(); uint8_t nextB();
uint32_t nextU(); uint32_t nextU();
@ -43,6 +51,17 @@ private:
int fNextByte; 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 { struct Fuzzable {
const char* name; const char* name;
void (*fn)(Fuzz*); void (*fn)(Fuzz*);

87
fuzz/FuzzPathop.cpp Normal file
View File

@ -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);
}

View File

@ -14,6 +14,8 @@
#include "SkImageEncoder.h" #include "SkImageEncoder.h"
#include "SkMallocPixelRef.h" #include "SkMallocPixelRef.h"
#include "SkPicture.h" #include "SkPicture.h"
#include "SkPicture.h"
#include "SkPicture.h"
#include "SkStream.h" #include "SkStream.h"
#include <cmath> #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::signalBug () { SkDebugf("Signal bug\n"); raise(SIGSEGV); }
void Fuzz::signalBoring() { SkDebugf("Signal boring\n"); exit(0); } 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> template <typename T>
T Fuzz::nextT() { T Fuzz::nextT() {
if (fNextByte + sizeof(T) > fBytes->size()) { if (fNextByte + sizeof(T) > fBytes->size()) {