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:
parent
0b86a3d43b
commit
0f3d2a6010
@ -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
|
// This cannot be inlined in DEFINE_string2 due to interleaved ifdefs
|
||||||
static constexpr char g_type_message[] = "How to interpret --bytes, one of:\n"
|
static constexpr char g_type_message[] = "How to interpret --bytes, one of:\n"
|
||||||
|
"android_codec\n"
|
||||||
"animated_image_decode\n"
|
"animated_image_decode\n"
|
||||||
"api\n"
|
"api\n"
|
||||||
"color_deserialize\n"
|
"color_deserialize\n"
|
||||||
"filter_fuzz (equivalent to Chrome's filter_fuzz_stub)\n"
|
"filter_fuzz (equivalent to Chrome's filter_fuzz_stub)\n"
|
||||||
"image_decode\n"
|
"image_decode\n"
|
||||||
|
"image_decode_incremental\n"
|
||||||
"image_mode\n"
|
"image_mode\n"
|
||||||
"image_scale\n"
|
"image_scale\n"
|
||||||
"json\n"
|
"json\n"
|
||||||
@ -69,11 +71,13 @@ static int fuzz_file(SkString path, SkString type);
|
|||||||
static uint8_t calculate_option(SkData*);
|
static uint8_t calculate_option(SkData*);
|
||||||
static SkString try_auto_detect(SkString path, SkString* name);
|
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_api(sk_sp<SkData> bytes, SkString name);
|
||||||
static void fuzz_color_deserialize(sk_sp<SkData>);
|
static void fuzz_color_deserialize(sk_sp<SkData>);
|
||||||
static void fuzz_filter_fuzz(sk_sp<SkData>);
|
static void fuzz_filter_fuzz(sk_sp<SkData>);
|
||||||
static void fuzz_img2(sk_sp<SkData>);
|
static void fuzz_image_decode(sk_sp<SkData>);
|
||||||
static void fuzz_animated_img(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_img(sk_sp<SkData>, uint8_t, uint8_t);
|
||||||
static void fuzz_json(sk_sp<SkData>);
|
static void fuzz_json(sk_sp<SkData>);
|
||||||
static void fuzz_path_deserialize(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());
|
SkDebugf("Could not autodetect type of %s\n", path.c_str());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
if (type.equals("android_codec")) {
|
||||||
|
fuzz_android_codec(bytes);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
if (type.equals("animated_image_decode")) {
|
if (type.equals("animated_image_decode")) {
|
||||||
fuzz_animated_img(bytes);
|
fuzz_animated_img(bytes);
|
||||||
return 0;
|
return 0;
|
||||||
@ -153,7 +160,11 @@ static int fuzz_file(SkString path, SkString type) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (type.equals("image_decode")) {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
if (type.equals("image_scale")) {
|
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
|
// maps clusterfuzz/oss-fuzz -> Skia's name
|
||||||
static std::map<std::string, std::string> cf_map = {
|
static std::map<std::string, std::string> cf_map = {
|
||||||
|
{"android_codec", "android_codec"},
|
||||||
{"animated_image_decode", "animated_image_decode"},
|
{"animated_image_decode", "animated_image_decode"},
|
||||||
{"image_decode", "image_decode"},
|
{"image_decode", "image_decode"},
|
||||||
|
{"image_decode_incremental", "image_decode_incremental"},
|
||||||
{"image_filter_deserialize", "filter_fuzz"},
|
{"image_filter_deserialize", "filter_fuzz"},
|
||||||
{"image_filter_deserialize_width", "filter_fuzz"},
|
{"image_filter_deserialize_width", "filter_fuzz"},
|
||||||
{"path_deserialize", "path_deserialize"},
|
{"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) {
|
static void fuzz_animated_img(sk_sp<SkData> bytes) {
|
||||||
FuzzAnimatedImage(bytes);
|
if (FuzzAnimatedImage(bytes)) {
|
||||||
SkDebugf("[terminated] Didn't crash while decoding/drawing animated image!\n");
|
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) {
|
static void fuzz_image_decode(sk_sp<SkData> bytes) {
|
||||||
FuzzImage(bytes);
|
if (FuzzImageDecode(bytes)) {
|
||||||
SkDebugf("[terminated] Didn't crash while decoding/drawing image!\n");
|
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) {
|
static void fuzz_img(sk_sp<SkData> bytes, uint8_t scale, uint8_t mode) {
|
||||||
// We can scale 1x, 2x, 4x, 8x, 16x
|
// We can scale 1x, 2x, 4x, 8x, 16x
|
||||||
scale = scale % 5;
|
scale = scale % 5;
|
||||||
|
@ -7,35 +7,33 @@
|
|||||||
|
|
||||||
#include "SkAndroidCodec.h"
|
#include "SkAndroidCodec.h"
|
||||||
#include "SkAnimatedImage.h"
|
#include "SkAnimatedImage.h"
|
||||||
#include "SkPaint.h"
|
|
||||||
#include "SkCanvas.h"
|
#include "SkCanvas.h"
|
||||||
#include "SkData.h"
|
#include "SkData.h"
|
||||||
#include "SkSurface.h"
|
#include "SkSurface.h"
|
||||||
|
|
||||||
void FuzzAnimatedImage(sk_sp<SkData> bytes) {
|
bool FuzzAnimatedImage(sk_sp<SkData> bytes) {
|
||||||
auto codec = SkAndroidCodec::MakeFromData(bytes);
|
auto codec = SkAndroidCodec::MakeFromData(bytes);
|
||||||
if (nullptr == codec) {
|
if (nullptr == codec) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
auto aImg = SkAnimatedImage::Make(std::move(codec));
|
auto aImg = SkAnimatedImage::Make(std::move(codec));
|
||||||
if (nullptr == aImg) {
|
if (nullptr == aImg) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto s = SkSurface::MakeRasterN32Premul(128, 128);
|
auto s = SkSurface::MakeRasterN32Premul(128, 128);
|
||||||
if (!s) {
|
if (!s) {
|
||||||
// May return nullptr in memory-constrained fuzzing environments
|
// May return nullptr in memory-constrained fuzzing environments
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkPaint p;
|
|
||||||
int escape = 0;
|
int escape = 0;
|
||||||
while (!aImg->isFinished() && escape < 100) {
|
while (!aImg->isFinished() && escape < 100) {
|
||||||
aImg->draw(s->getCanvas());
|
aImg->draw(s->getCanvas());
|
||||||
escape++;
|
escape++;
|
||||||
aImg->decodeNextFrame();
|
aImg->decodeNextFrame();
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(IS_FUZZING_WITH_LIBFUZZER)
|
#if defined(IS_FUZZING_WITH_LIBFUZZER)
|
||||||
|
@ -11,27 +11,27 @@
|
|||||||
#include "SkData.h"
|
#include "SkData.h"
|
||||||
#include "SkSurface.h"
|
#include "SkSurface.h"
|
||||||
|
|
||||||
void FuzzImage(sk_sp<SkData> bytes) {
|
bool FuzzImageDecode(sk_sp<SkData> bytes) {
|
||||||
auto img = SkImage::MakeFromEncoded(bytes);
|
auto img = SkImage::MakeFromEncoded(bytes);
|
||||||
if (nullptr == img.get()) {
|
if (nullptr == img.get()) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto s = SkSurface::MakeRasterN32Premul(128, 128);
|
auto s = SkSurface::MakeRasterN32Premul(128, 128);
|
||||||
if (!s) {
|
if (!s) {
|
||||||
// May return nullptr in memory-constrained fuzzing environments
|
// May return nullptr in memory-constrained fuzzing environments
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkPaint p;
|
SkPaint p;
|
||||||
s->getCanvas()->drawImage(img, 0, 0, &p);
|
s->getCanvas()->drawImage(img, 0, 0, &p);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(IS_FUZZING_WITH_LIBFUZZER)
|
#if defined(IS_FUZZING_WITH_LIBFUZZER)
|
||||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||||
auto bytes = SkData::MakeWithoutCopy(data, size);
|
auto bytes = SkData::MakeWithoutCopy(data, size);
|
||||||
FuzzImage(bytes);
|
FuzzImageDecode(bytes);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#include "SkCodec.h"
|
#include "SkCodec.h"
|
||||||
#include "SkData.h"
|
#include "SkData.h"
|
||||||
|
|
||||||
bool FuzzIncrementalImage(sk_sp<SkData> bytes) {
|
bool FuzzIncrementalImageDecode(sk_sp<SkData> bytes) {
|
||||||
auto codec = SkCodec::MakeFromData(bytes);
|
auto codec = SkCodec::MakeFromData(bytes);
|
||||||
if (!codec) {
|
if (!codec) {
|
||||||
return false;
|
return false;
|
||||||
@ -48,7 +48,7 @@ bool FuzzIncrementalImage(sk_sp<SkData> bytes) {
|
|||||||
#if defined(IS_FUZZING_WITH_LIBFUZZER)
|
#if defined(IS_FUZZING_WITH_LIBFUZZER)
|
||||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||||
auto bytes = SkData::MakeWithoutCopy(data, size);
|
auto bytes = SkData::MakeWithoutCopy(data, size);
|
||||||
FuzzIncrementalImage(bytes);
|
FuzzIncrementalImageDecode(bytes);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user