From edef8ec4b24f9d2ce76e4c53304e25853888bee4 Mon Sep 17 00:00:00 2001 From: Kevin Lubick Date: Tue, 9 Jan 2018 15:32:58 -0500 Subject: Refactor SerializedImageFilter to avoid duplicate code After this CL, we have 3.5 options for fuzzing ImageFilter 1. Create it from API calls and then draw it fuzz -t api -n ImageFilter -b [input] 2. Deserialize a fuzzed stream into an ImageFilter (this is what Chromium's filter_fuzz_stub does) fuzz -t filter_fuzz -b [input] 3. Create an ImageFilter from API calls, serialize it, apply some mutations to the stream, deserialize it, then draw it. fuzz -t api -n SerializedImageFilter -b [input] 3.5 Create ImageFilters as part of our more general canvas fuzzers. fuzz -t api -n RasterN32Canvas -b [input] (and others) Previously, the SerializedImageFilter had its own, slightly stale and prone to stack-overflow way of making an image filter. This CL re-uses what we already do for Canvas fuzzing and removes that dead code. Additionally, there is a way to easily generate a corpus for the filter_fuzz type, via SerializedImageFilter. Bug: skia: Change-Id: I31bb4ffce2abf1c1a6d0a7000e5aceb8d7b38b65 Reviewed-on: https://skia-review.googlesource.com/92142 Reviewed-by: Hal Canary Commit-Queue: Kevin Lubick --- fuzz/FuzzCanvas.cpp | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) (limited to 'fuzz/FuzzCanvas.cpp') diff --git a/fuzz/FuzzCanvas.cpp b/fuzz/FuzzCanvas.cpp index e125188e70..5bedf9123b 100644 --- a/fuzz/FuzzCanvas.cpp +++ b/fuzz/FuzzCanvas.cpp @@ -23,6 +23,7 @@ #include "SkRegion.h" #include "SkSurface.h" #include "SkTypeface.h" +#include "SkOSFile.h" // EFFECTS #include "Sk1DPathEffect.h" @@ -1780,6 +1781,72 @@ DEF_FUZZ(RasterN32CanvasViaSerialization, fuzz) { surface->getCanvas()->drawPicture(deserialized); } +DEF_FUZZ(ImageFilter, fuzz) { + auto fil = make_fuzz_imageFilter(fuzz, 20); + + SkPaint paint; + paint.setImageFilter(fil); + SkBitmap bitmap; + SkCanvas canvas(bitmap); + canvas.saveLayer(SkRect::MakeWH(500, 500), &paint); +} + + +//SkRandom _rand; +#define SK_ADD_RANDOM_BIT_FLIPS + +DEF_FUZZ(SerializedImageFilter, fuzz) { + auto filter = make_fuzz_imageFilter(fuzz, 20); + auto data = filter->serialize(); + const unsigned char* ptr = static_cast(data->data()); + size_t len = data->size(); +#ifdef SK_ADD_RANDOM_BIT_FLIPS + unsigned char* p = const_cast(ptr); + for (size_t i = 0; i < len; ++i, ++p) { + uint8_t j; + fuzz->nextRange(&j, 1, 250); + if (j == 1) { // 0.4% of the time, flip a bit or byte + uint8_t k; + fuzz->nextRange(&k, 1, 10); + if (k == 1) { // Then 10% of the time, change a whole byte + uint8_t s; + fuzz->nextRange(&s, 0, 2); + switch(s) { + case 0: + *p ^= 0xFF; // Flip entire byte + break; + case 1: + *p = 0xFF; // Set all bits to 1 + break; + case 2: + *p = 0x00; // Set all bits to 0 + break; + } + } else { + uint8_t s; + fuzz->nextRange(&s, 0, 7); + *p ^= (1 << 7); + } + } + } +#endif // SK_ADD_RANDOM_BIT_FLIPS + auto deserializedFil = SkImageFilter::Deserialize(ptr, len); + + // uncomment below to write out a serialized image filter (to make corpus + // for -t filter_fuzz) + // SkString s("./serialized_filters/sf"); + // s.appendU32(_rand.nextU()); + // auto file = sk_fopen(s.c_str(), SkFILE_Flags::kWrite_SkFILE_Flag); + // sk_fwrite(data->bytes(), data->size(), file); + // sk_fclose(file); + + SkPaint paint; + paint.setImageFilter(deserializedFil); + SkBitmap bitmap; + SkCanvas canvas(bitmap); + canvas.saveLayer(SkRect::MakeWH(500, 500), &paint); +} + #if SK_SUPPORT_GPU static void fuzz_ganesh(Fuzz* fuzz, GrContext* context) { SkASSERT(context); -- cgit v1.2.3