Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "Fuzz.h" | 8 #include "Fuzz.h" |
| 9 #include "SkCanvas.h" | |
| 9 #include "SkCommandLineFlags.h" | 10 #include "SkCommandLineFlags.h" |
| 11 #include "SkData.h" | |
| 12 #include "SkImage.h" | |
| 13 #include "SkImageEncoder.h" | |
| 14 #include "SkImageDecoder.h" | |
|
scroggo
2016/01/19 15:35:39
We're actually interested in testing SkCodec, not
| |
| 15 #include "SkForceLinking.h" | |
| 16 #include "SkPicture.h" | |
| 17 #include "SkStream.h" | |
| 18 | |
| 10 #include <signal.h> | 19 #include <signal.h> |
| 11 #include <stdlib.h> | 20 #include <stdlib.h> |
| 21 #include <cmath> | |
| 22 | |
| 23 __SK_FORCE_IMAGE_DECODER_LINKING; | |
| 12 | 24 |
| 13 DEFINE_string2(bytes, b, "", "A path to a file containing fuzzed bytes."); | 25 DEFINE_string2(bytes, b, "", "A path to a file containing fuzzed bytes."); |
| 14 DEFINE_string2(match, m, "", "The usual --match, applied to DEF_FUZZ names."); | 26 DEFINE_string2(match, m, "", "The usual --match, applied to DEF_FUZZ names."); |
| 15 | 27 |
| 28 DEFINE_string2(file, f, "", "The path to a binary file."); | |
|
mtklein
2016/01/19 16:17:25
What's the difference between -b and -f? Let's pi
kjlubick
2016/01/20 13:08:15
Done
| |
| 29 DEFINE_string(mode, "", "The mode in which to treat the binary file. Can be 'im age', 'skp'"); | |
|
mtklein
2016/01/19 16:17:25
DEFINE_string(mode, "api", "How to interpret --byt
kjlubick
2016/01/20 13:08:15
Done
| |
| 30 DEFINE_bool(debug, false, "If the output of any renderings should be dumped as a png."); | |
|
mtklein
2016/01/19 16:17:25
DEFINE_string(dump, "", "If not empty, dump 'image
kjlubick
2016/01/20 13:08:15
Done.
| |
| 31 | |
| 32 void runSingleTest(); | |
| 33 int decodeImage(); | |
| 34 int decodeSkp(); | |
| 35 | |
| 16 int main(int argc, char** argv) { | 36 int main(int argc, char** argv) { |
| 17 SkCommandLineFlags::Parse(argc, argv); | 37 SkCommandLineFlags::Parse(argc, argv); |
| 18 | 38 |
| 19 if (FLAGS_bytes.isEmpty()) { | 39 if (FLAGS_mode.isEmpty()) { |
| 20 SkDebugf("Usage: %s -b <path/to/fuzzed.data> [-m pattern]\n", argv[0]); | 40 runSingleTest(); |
| 21 return 1; | 41 return 0; |
| 22 } | 42 } |
| 43 | |
| 44 if (0 == strcmp(FLAGS_mode[0], "image")) { | |
| 45 return decodeImage(); | |
| 46 } else if (0 == strcmp(FLAGS_mode[0], "skp")) { | |
| 47 return decodeSkp(); | |
| 48 } | |
| 49 | |
| 50 SkDebugf("Usage: %s -b <path/to/fuzzed.data> [-m pattern]\n", argv[0]); | |
| 51 SkDebugf("or\n"); | |
| 52 SkDebugf("Usage: %s --mode [mode] -f <path/to/fuzzed.file>\n", argv[0]); | |
| 53 return 1; | |
| 54 } | |
| 55 | |
| 56 void runSingleTest() { | |
| 23 SkAutoTUnref<SkData> bytes(SkData::NewFromFileName(FLAGS_bytes[0])); | 57 SkAutoTUnref<SkData> bytes(SkData::NewFromFileName(FLAGS_bytes[0])); |
| 24 | 58 |
| 25 for (auto r = SkTRegistry<Fuzzable>::Head(); r; r = r->next()) { | 59 for (auto r = SkTRegistry<Fuzzable>::Head(); r; r = r->next()) { |
| 26 auto fuzzable = r->factory(); | 60 auto fuzzable = r->factory(); |
| 27 if (!SkCommandLineFlags::ShouldSkip(FLAGS_match, fuzzable.name)) { | 61 if (!SkCommandLineFlags::ShouldSkip(FLAGS_match, fuzzable.name)) { |
| 28 SkDebugf("Fuzzing %s...\n", fuzzable.name); | 62 SkDebugf("Fuzzing %s...\n", fuzzable.name); |
| 29 Fuzz fuzz(bytes); | 63 Fuzz fuzz(bytes); |
| 30 fuzzable.fn(&fuzz); | 64 fuzzable.fn(&fuzz); |
| 65 return; | |
| 31 } | 66 } |
| 32 } | 67 } |
| 68 } | |
| 69 | |
| 70 int decodeImage() { | |
| 71 if (FLAGS_file.isEmpty()) { | |
| 72 SkDebugf("Usage: fuzz --mode image --file <path/to/fuzzed.image>\n"); | |
| 73 return 1; | |
| 74 } | |
| 75 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(FLAGS_file[0])); | |
|
mtklein
2016/01/19 16:17:25
It looks like you're copying and pasting. Let's s
kjlubick
2016/01/20 13:08:15
I'm going to keep the functions here for easier fu
| |
| 76 if (!encoded) { | |
| 77 SkDebugf("Could not read %s\n", FLAGS_file[0]); | |
| 78 return 2; | |
| 79 } | |
| 80 SkBitmap bitmap; | |
| 81 if (!SkImageDecoder::DecodeMemory(encoded->data(), encoded->size(), &bitmap) ) { | |
| 82 SkDebugf("Could not decode image.\n"); | |
| 83 return 3; | |
| 84 } | |
| 85 encoded.reset((SkData*)nullptr); // Might as well drop this when we're done with it. | |
|
mtklein
2016/01/19 16:17:25
Actually, here in this program we probably don't n
kjlubick
2016/01/20 13:08:14
Done.
| |
| 86 | |
| 87 SkImage::NewFromBitmap(bitmap); | |
| 88 SkDebugf("Created an SkImage!\n"); | |
| 89 if (FLAGS_debug) { | |
| 90 SkImageEncoder::EncodeFile("debug.png", bitmap, SkImageEncoder::kPNG_Typ e, 100); | |
| 91 } | |
| 33 return 0; | 92 return 0; |
| 34 } | 93 } |
| 35 | 94 |
| 95 static const SkRect kSKPViewport = {0,0, 1000,1000}; | |
| 96 | |
| 97 int decodeSkp() { | |
| 98 if (FLAGS_file.isEmpty()) { | |
| 99 SkDebugf("Usage: fuzz --mode skp --file <path/to/fuzzed.skp>\n"); | |
| 100 return 1; | |
| 101 } | |
| 102 SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(FLAGS_file[0])); | |
| 103 if (!stream) { | |
| 104 SkDebugf("Couldn't read %s.", FLAGS_file[0]); | |
| 105 return 2; | |
| 106 } | |
| 107 SkDebugf("Decoding"); | |
| 108 SkAutoTUnref<SkPicture> pic(SkPicture::CreateFromStream(stream)); | |
| 109 if (!pic) { | |
| 110 SkDebugf("Couldn't decode as a picture."); | |
| 111 return 3; | |
| 112 } | |
| 113 stream.reset((SkStream*)nullptr); // Might as well drop this when we're don e with it. | |
| 114 SkDebugf("Rendering"); | |
| 115 SkBitmap bitmap; | |
| 116 if (FLAGS_debug) { | |
| 117 bitmap.allocN32Pixels(4000, 4000); | |
|
mtklein
2016/01/19 16:17:25
Probably better to allocate pixels to fit pic->cul
kjlubick
2016/01/20 13:08:14
Done.
| |
| 118 } | |
| 119 SkCanvas canvas(bitmap); | |
| 120 canvas.clipRect(kSKPViewport); | |
| 121 canvas.drawPicture(pic); | |
| 122 SkDebugf("Decoded and rendered an SkPicture!\n"); | |
| 123 if (FLAGS_debug) { | |
| 124 SkImageEncoder::EncodeFile("debug.png", bitmap, SkImageEncoder::kPNG_Typ e, 100); | |
| 125 } | |
| 126 return 0; | |
| 127 } | |
| 36 | 128 |
| 37 Fuzz::Fuzz(SkData* bytes) : fBytes(SkSafeRef(bytes)), fNextByte(0) {} | 129 Fuzz::Fuzz(SkData* bytes) : fBytes(SkSafeRef(bytes)), fNextByte(0) {} |
| 38 | 130 |
| 39 void Fuzz::signalBug () { raise(SIGSEGV); } | 131 void Fuzz::signalBug () { raise(SIGSEGV); } |
| 40 void Fuzz::signalBoring() { exit(0); } | 132 void Fuzz::signalBoring() { exit(0); } |
| 41 | 133 |
| 42 template <typename T> | 134 template <typename T> |
| 43 T Fuzz::nextT() { | 135 T Fuzz::nextT() { |
| 44 if (fNextByte + sizeof(T) > fBytes->size()) { | 136 if (fNextByte + sizeof(T) > fBytes->size()) { |
| 45 this->signalBoring(); | 137 this->signalBoring(); |
| 46 } | 138 } |
| 47 | 139 |
| 48 T val; | 140 T val; |
| 49 memcpy(&val, fBytes->bytes() + fNextByte, sizeof(T)); | 141 memcpy(&val, fBytes->bytes() + fNextByte, sizeof(T)); |
| 50 fNextByte += sizeof(T); | 142 fNextByte += sizeof(T); |
| 51 return val; | 143 return val; |
| 52 } | 144 } |
| 53 | 145 |
| 54 uint8_t Fuzz::nextB() { return this->nextT<uint8_t >(); } | 146 uint8_t Fuzz::nextB() { return this->nextT<uint8_t >(); } |
| 55 uint32_t Fuzz::nextU() { return this->nextT<uint32_t>(); } | 147 uint32_t Fuzz::nextU() { return this->nextT<uint32_t>(); } |
| 56 float Fuzz::nextF() { return this->nextT<float >(); } | 148 float Fuzz::nextF() { return this->nextT<float >(); } |
| 57 | 149 |
| OLD | NEW |