Add new Codec fuzzers to FuzzMain

Already in oss-fuzz:
https://github.com/google/oss-fuzz/pull/1882

This tweaks some names and return types to be more
consistent.

Bug: skia:
Change-Id: Id7e2e00bd4e7c7758d616d102195c0291bc37d9f
Reviewed-on: https://skia-review.googlesource.com/c/163124
Reviewed-by: Leon Scroggins <scroggo@google.com>
Commit-Queue: Kevin Lubick <kjlubick@google.com>
This commit is contained in:
Kevin Lubick 2018-10-17 10:24:44 -04:00 committed by Skia Commit-Bot
parent 0b86a3d43b
commit 0f3d2a6010
4 changed files with 69 additions and 25 deletions

View File

@ -45,11 +45,13 @@ DEFINE_bool2(verbose, v, false, "Print more information while fuzzing.");
// This cannot be inlined in DEFINE_string2 due to interleaved ifdefs
static constexpr char g_type_message[] = "How to interpret --bytes, one of:\n"
"android_codec\n"
"animated_image_decode\n"
"api\n"
"color_deserialize\n"
"filter_fuzz (equivalent to Chrome's filter_fuzz_stub)\n"
"image_decode\n"
"image_decode_incremental\n"
"image_mode\n"
"image_scale\n"
"json\n"
@ -69,11 +71,13 @@ static int fuzz_file(SkString path, SkString type);
static uint8_t calculate_option(SkData*);
static SkString try_auto_detect(SkString path, SkString* name);
static void fuzz_android_codec(sk_sp<SkData>);
static void fuzz_animated_img(sk_sp<SkData>);
static void fuzz_api(sk_sp<SkData> bytes, SkString name);
static void fuzz_color_deserialize(sk_sp<SkData>);
static void fuzz_filter_fuzz(sk_sp<SkData>);
static void fuzz_img2(sk_sp<SkData>);
static void fuzz_animated_img(sk_sp<SkData>);
static void fuzz_image_decode(sk_sp<SkData>);
static void fuzz_image_decode_incremental(sk_sp<SkData>);
static void fuzz_img(sk_sp<SkData>, uint8_t, uint8_t);
static void fuzz_json(sk_sp<SkData>);
static void fuzz_path_deserialize(sk_sp<SkData>);
@ -135,7 +139,10 @@ static int fuzz_file(SkString path, SkString type) {
SkDebugf("Could not autodetect type of %s\n", path.c_str());
return 1;
}
if (type.equals("android_codec")) {
fuzz_android_codec(bytes);
return 0;
}
if (type.equals("animated_image_decode")) {
fuzz_animated_img(bytes);
return 0;
@ -153,7 +160,11 @@ static int fuzz_file(SkString path, SkString type) {
return 0;
}
if (type.equals("image_decode")) {
fuzz_img2(bytes);
fuzz_image_decode(bytes);
return 0;
}
if (type.equals("image_decode_incremental")) {
fuzz_image_decode_incremental(bytes);
return 0;
}
if (type.equals("image_scale")) {
@ -229,8 +240,10 @@ static std::map<std::string, std::string> cf_api_map = {
// maps clusterfuzz/oss-fuzz -> Skia's name
static std::map<std::string, std::string> cf_map = {
{"android_codec", "android_codec"},
{"animated_image_decode", "animated_image_decode"},
{"image_decode", "image_decode"},
{"image_decode_incremental", "image_decode_incremental"},
{"image_filter_deserialize", "filter_fuzz"},
{"image_filter_deserialize_width", "filter_fuzz"},
{"path_deserialize", "path_deserialize"},
@ -332,20 +345,53 @@ static void dump_png(SkBitmap bitmap) {
}
}
void FuzzAnimatedImage(sk_sp<SkData> bytes);
bool FuzzAnimatedImage(sk_sp<SkData> bytes);
static void fuzz_animated_img(sk_sp<SkData> bytes) {
FuzzAnimatedImage(bytes);
SkDebugf("[terminated] Didn't crash while decoding/drawing animated image!\n");
if (FuzzAnimatedImage(bytes)) {
SkDebugf("[terminated] Success from decoding/drawing animated image!\n");
return;
}
SkDebugf("[terminated] Could not decode or draw animated image.\n");
}
void FuzzImage(sk_sp<SkData> bytes);
bool FuzzImageDecode(sk_sp<SkData> bytes);
static void fuzz_img2(sk_sp<SkData> bytes) {
FuzzImage(bytes);
SkDebugf("[terminated] Didn't crash while decoding/drawing image!\n");
static void fuzz_image_decode(sk_sp<SkData> bytes) {
if (FuzzImageDecode(bytes)) {
SkDebugf("[terminated] Success from decoding/drawing image!\n");
return;
}
SkDebugf("[terminated] Could not decode or draw image.\n");
}
bool FuzzIncrementalImageDecode(sk_sp<SkData> bytes);
static void fuzz_image_decode_incremental(sk_sp<SkData> bytes) {
if (FuzzIncrementalImageDecode(bytes)) {
SkDebugf("[terminated] Success using incremental decode!\n");
return;
}
SkDebugf("[terminated] Could not incrementally decode and image.\n");
}
bool FuzzAndroidCodec(sk_sp<SkData> bytes, uint8_t sampleSize);
static void fuzz_android_codec(sk_sp<SkData> bytes) {
Fuzz fuzz(bytes);
uint8_t sampleSize;
fuzz.nextRange(&sampleSize, 1, 64);
bytes = SkData::MakeSubset(bytes.get(), 1, bytes->size() - 1);
if (FuzzAndroidCodec(bytes, sampleSize)) {
SkDebugf("[terminated] Success on Android Codec sampleSize=%u!\n", sampleSize);
return;
}
SkDebugf("[terminated] Could not use Android Codec sampleSize=%u!\n", sampleSize);
}
// This is a "legacy" fuzzer that likely does too much. It was based off of how
// DM reads in images. image_decode, image_decode_incremental and android_codec
// are more targeted fuzzers that do a subset of what this one does.
static void fuzz_img(sk_sp<SkData> bytes, uint8_t scale, uint8_t mode) {
// We can scale 1x, 2x, 4x, 8x, 16x
scale = scale % 5;

View File

@ -7,35 +7,33 @@
#include "SkAndroidCodec.h"
#include "SkAnimatedImage.h"
#include "SkPaint.h"
#include "SkCanvas.h"
#include "SkData.h"
#include "SkSurface.h"
void FuzzAnimatedImage(sk_sp<SkData> bytes) {
bool FuzzAnimatedImage(sk_sp<SkData> bytes) {
auto codec = SkAndroidCodec::MakeFromData(bytes);
if (nullptr == codec) {
return;
return false;
}
auto aImg = SkAnimatedImage::Make(std::move(codec));
if (nullptr == aImg) {
return;
return false;
}
auto s = SkSurface::MakeRasterN32Premul(128, 128);
if (!s) {
// May return nullptr in memory-constrained fuzzing environments
return;
return false;
}
SkPaint p;
int escape = 0;
while (!aImg->isFinished() && escape < 100) {
aImg->draw(s->getCanvas());
escape++;
aImg->decodeNextFrame();
}
return true;
}
#if defined(IS_FUZZING_WITH_LIBFUZZER)

View File

@ -11,27 +11,27 @@
#include "SkData.h"
#include "SkSurface.h"
void FuzzImage(sk_sp<SkData> bytes) {
bool FuzzImageDecode(sk_sp<SkData> bytes) {
auto img = SkImage::MakeFromEncoded(bytes);
if (nullptr == img.get()) {
return;
return false;
}
auto s = SkSurface::MakeRasterN32Premul(128, 128);
if (!s) {
// May return nullptr in memory-constrained fuzzing environments
return;
return false;
}
SkPaint p;
s->getCanvas()->drawImage(img, 0, 0, &p);
return true;
}
#if defined(IS_FUZZING_WITH_LIBFUZZER)
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
auto bytes = SkData::MakeWithoutCopy(data, size);
FuzzImage(bytes);
FuzzImageDecode(bytes);
return 0;
}
#endif

View File

@ -9,7 +9,7 @@
#include "SkCodec.h"
#include "SkData.h"
bool FuzzIncrementalImage(sk_sp<SkData> bytes) {
bool FuzzIncrementalImageDecode(sk_sp<SkData> bytes) {
auto codec = SkCodec::MakeFromData(bytes);
if (!codec) {
return false;
@ -48,7 +48,7 @@ bool FuzzIncrementalImage(sk_sp<SkData> bytes) {
#if defined(IS_FUZZING_WITH_LIBFUZZER)
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
auto bytes = SkData::MakeWithoutCopy(data, size);
FuzzIncrementalImage(bytes);
FuzzIncrementalImageDecode(bytes);
return 0;
}
#endif