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:
parent
e51c356ae4
commit
e565450d0b
19
fuzz/Fuzz.h
19
fuzz/Fuzz.h
@ -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
87
fuzz/FuzzPathop.cpp
Normal 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);
|
||||||
|
}
|
@ -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()) {
|
||||||
|
Loading…
Reference in New Issue
Block a user