diff options
author | Kevin Lubick <kjlubick@google.com> | 2018-10-23 09:28:48 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-10-23 14:24:22 +0000 |
commit | f84ded269e7ab95d165b3231bc35498afc1b1fe7 (patch) | |
tree | f7d2d7c2562ebafa0933cb70dee51a040da55ffe /fuzz | |
parent | 00766bf8dda1118ce31f3b6c853a279b17d3c2bf (diff) | |
download | platform_external_skqp-f84ded269e7ab95d165b3231bc35498afc1b1fe7.tar.gz platform_external_skqp-f84ded269e7ab95d165b3231bc35498afc1b1fe7.tar.bz2 platform_external_skqp-f84ded269e7ab95d165b3231bc35498afc1b1fe7.zip |
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>
Diffstat (limited to 'fuzz')
-rw-r--r-- | fuzz/Fuzz.h | 13 | ||||
-rw-r--r-- | fuzz/FuzzMain.cpp | 2 | ||||
-rw-r--r-- | fuzz/FuzzPathop.cpp | 87 |
3 files changed, 98 insertions, 4 deletions
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 <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> 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<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"} }; 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<SkPathOp>(op % (kLastOp + 1))); + } + + SkPath result; + builder.resolve(&result); +} |