Add Legacy fuzz reproducer
Make FuzzEnum always use uint32_t to make it consistent (we were seeing some Windows setups have underlying type return int and not unsigned int that we saw on Linux) Bug: 897455 Change-Id: Ia8c97e59bb498d959a9a30abcb61731f4bd145cf Reviewed-on: https://skia-review.googlesource.com/c/164240 Reviewed-by: Cary Clark <caryclark@google.com> Commit-Queue: Kevin Lubick <kjlubick@google.com>
This commit is contained in:
parent
00766bf8dd
commit
f84ded269e
13
fuzz/Fuzz.h
13
fuzz/Fuzz.h
@ -27,10 +27,18 @@ public:
|
||||
// Returns the total number of "random" bytes available.
|
||||
size_t size() { return fBytes->size(); }
|
||||
// Returns if there are no bytes remaining for fuzzing.
|
||||
bool exhausted(){
|
||||
bool exhausted() {
|
||||
return fBytes->size() == fNextByte;
|
||||
}
|
||||
|
||||
size_t remaining() {
|
||||
return fBytes->size() - fNextByte;
|
||||
}
|
||||
|
||||
void deplete() {
|
||||
fNextByte = fBytes->size();
|
||||
}
|
||||
|
||||
// next() loads fuzzed bytes into the variable passed in by pointer.
|
||||
// We use this approach instead of T next() because different compilers
|
||||
// evaluate function parameters in different orders. If fuzz->next()
|
||||
@ -124,8 +132,7 @@ inline void Fuzz::nextRange(T* n, Min min, Max max) {
|
||||
|
||||
template <typename T, typename Min, typename Max>
|
||||
inline void Fuzz::nextEnum(T* value, Min rmin, Max rmax) {
|
||||
using U = skstd::underlying_type_t<T>;
|
||||
this->nextRange((U*)value, (U)rmin, (U)rmax);
|
||||
this->nextRange((uint32_t*)value, (uint32_t)rmin, (uint32_t)rmax);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
@ -234,7 +234,7 @@ static std::map<std::string, std::string> cf_api_map = {
|
||||
{"api_raster_n32_canvas", "RasterN32Canvas"},
|
||||
{"jpeg_encoder", "JPEGEncoder"},
|
||||
{"png_encoder", "PNGEncoder"},
|
||||
{"skia_pathop_fuzzer", "Pathop"},
|
||||
{"skia_pathop_fuzzer", "LegacyChromiumPathop"},
|
||||
{"webp_encoder", "WEBPEncoder"}
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user