From f84ded269e7ab95d165b3231bc35498afc1b1fe7 Mon Sep 17 00:00:00 2001 From: Kevin Lubick Date: Tue, 23 Oct 2018 09:28:48 -0400 Subject: 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 Commit-Queue: Kevin Lubick --- fuzz/Fuzz.h | 13 ++++++-- fuzz/FuzzMain.cpp | 2 +- fuzz/FuzzPathop.cpp | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+), 4 deletions(-) (limited to 'fuzz') diff --git a/fuzz/Fuzz.h b/fuzz/Fuzz.h index b27e04d341..bfee1b3b4c 100644 --- a/fuzz/Fuzz.h +++ b/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 inline void Fuzz::nextEnum(T* value, Min rmin, Max rmax) { - using U = skstd::underlying_type_t; - this->nextRange((U*)value, (U)rmin, (U)rmax); + this->nextRange((uint32_t*)value, (uint32_t)rmin, (uint32_t)rmax); } template diff --git a/fuzz/FuzzMain.cpp b/fuzz/FuzzMain.cpp index 0e095ad154..0ba3fc96a2 100644 --- a/fuzz/FuzzMain.cpp +++ b/fuzz/FuzzMain.cpp @@ -234,7 +234,7 @@ static std::map 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"} }; diff --git a/fuzz/FuzzPathop.cpp b/fuzz/FuzzPathop.cpp index fe7b237f5e..7aa229ee8c 100644 --- a/fuzz/FuzzPathop.cpp +++ b/fuzz/FuzzPathop.cpp @@ -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(op % (kLastOp + 1))); + } + + SkPath result; + builder.resolve(&result); +} -- cgit v1.2.3