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 "SkCanvas.h" |
10 #include "SkCodec.h" | 10 #include "SkCodec.h" |
11 #include "SkCommandLineFlags.h" | 11 #include "SkCommandLineFlags.h" |
12 #include "SkData.h" | 12 #include "SkData.h" |
13 #include "SkImage.h" | 13 #include "SkImage.h" |
14 #include "SkImageEncoder.h" | 14 #include "SkImageEncoder.h" |
15 #include "SkMallocPixelRef.h" | 15 #include "SkMallocPixelRef.h" |
16 #include "SkPicture.h" | 16 #include "SkPicture.h" |
17 #include "SkStream.h" | 17 #include "SkStream.h" |
18 | 18 |
19 #include <cmath> | 19 #include <cmath> |
20 #include <signal.h> | 20 #include <signal.h> |
21 #include <stdlib.h> | 21 #include <stdlib.h> |
22 | 22 |
23 DEFINE_string2(bytes, b, "", "A path to a file. This can be the fuzz bytes or a
binary to parse."); | 23 DEFINE_string2(bytes, b, "", "A path to a file. This can be the fuzz bytes or a
binary to parse."); |
24 DEFINE_string2(name, n, "", "If --type is 'api', fuzz the API with this name."); | 24 DEFINE_string2(name, n, "", "If --type is 'api', fuzz the API with this name."); |
25 | 25 |
26 DEFINE_string2(type, t, "api", "How to interpret --bytes, either 'image_scale',
'image_mode', 'skp', or 'api'."); | 26 DEFINE_string2(type, t, "api", "How to interpret --bytes, either 'image_scale',
'image_mode', 'skp', 'icc', or 'api'."); |
27 DEFINE_string2(dump, d, "", "If not empty, dump 'image*' or 'skp' types as a PNG
with this name."); | 27 DEFINE_string2(dump, d, "", "If not empty, dump 'image*' or 'skp' types as a PNG
with this name."); |
28 | 28 |
29 static int printUsage(const char* name) { | 29 static int printUsage(const char* name) { |
30 SkDebugf("Usage: %s -t <type> -b <path/to/file> [-n api-to-fuzz]\n", name); | 30 SkDebugf("Usage: %s -t <type> -b <path/to/file> [-n api-to-fuzz]\n", name); |
31 return 1; | 31 return 1; |
32 } | 32 } |
33 static uint8_t calculate_option(SkData*); | 33 static uint8_t calculate_option(SkData*); |
34 | 34 |
35 static int fuzz_api(SkData*); | 35 static int fuzz_api(SkData*); |
36 static int fuzz_img(SkData*, uint8_t, uint8_t); | 36 static int fuzz_img(SkData*, uint8_t, uint8_t); |
37 static int fuzz_skp(SkData*); | 37 static int fuzz_skp(SkData*); |
| 38 static int fuzz_icc(SkData*); |
38 | 39 |
39 int main(int argc, char** argv) { | 40 int main(int argc, char** argv) { |
40 SkCommandLineFlags::Parse(argc, argv); | 41 SkCommandLineFlags::Parse(argc, argv); |
41 | 42 |
42 const char* path = FLAGS_bytes.isEmpty() ? argv[0] : FLAGS_bytes[0]; | 43 const char* path = FLAGS_bytes.isEmpty() ? argv[0] : FLAGS_bytes[0]; |
43 SkAutoTUnref<SkData> bytes(SkData::NewFromFileName(path)); | 44 SkAutoTUnref<SkData> bytes(SkData::NewFromFileName(path)); |
44 if (!bytes) { | 45 if (!bytes) { |
45 SkDebugf("Could not read %s\n", path); | 46 SkDebugf("Could not read %s\n", path); |
46 return 2; | 47 return 2; |
47 } | 48 } |
48 | 49 |
49 uint8_t option = calculate_option(bytes); | 50 uint8_t option = calculate_option(bytes); |
50 | 51 |
51 if (!FLAGS_type.isEmpty()) { | 52 if (!FLAGS_type.isEmpty()) { |
52 switch (FLAGS_type[0][0]) { | 53 switch (FLAGS_type[0][0]) { |
53 case 'a': return fuzz_api(bytes); | 54 case 'a': return fuzz_api(bytes); |
54 | 55 |
55 case 'i': | 56 case 'i': |
| 57 if (FLAGS_type[0][1] == 'c') { //icc |
| 58 return fuzz_icc(bytes); |
| 59 } |
56 // We only allow one degree of freedom to avoid a search space e
xplosion for afl-fuzz. | 60 // We only allow one degree of freedom to avoid a search space e
xplosion for afl-fuzz. |
57 if (FLAGS_type[0][6] == 's') { // image_scale | 61 if (FLAGS_type[0][6] == 's') { // image_scale |
58 return fuzz_img(bytes, option, 0); | 62 return fuzz_img(bytes, option, 0); |
59 } | 63 } |
60 // image_mode | 64 // image_mode |
61 return fuzz_img(bytes, 0, option); | 65 return fuzz_img(bytes, 0, option); |
62 case 's': return fuzz_skp(bytes); | 66 case 's': return fuzz_skp(bytes); |
63 } | 67 } |
64 } | 68 } |
65 return printUsage(argv[0]); | 69 return printUsage(argv[0]); |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
365 SkIRect size = pic->cullRect().roundOut(); | 369 SkIRect size = pic->cullRect().roundOut(); |
366 bitmap.allocN32Pixels(size.width(), size.height()); | 370 bitmap.allocN32Pixels(size.width(), size.height()); |
367 } | 371 } |
368 SkCanvas canvas(bitmap); | 372 SkCanvas canvas(bitmap); |
369 canvas.drawPicture(pic); | 373 canvas.drawPicture(pic); |
370 SkDebugf("[terminated] Success! Decoded and rendered an SkPicture!\n"); | 374 SkDebugf("[terminated] Success! Decoded and rendered an SkPicture!\n"); |
371 dump_png(bitmap); | 375 dump_png(bitmap); |
372 return 0; | 376 return 0; |
373 } | 377 } |
374 | 378 |
| 379 int fuzz_icc(SkData* bytes) { |
| 380 sk_sp<SkColorSpace> space(SkColorSpace::NewICC(bytes->data(), bytes->size())
); |
| 381 if (!space) { |
| 382 SkDebugf("[terminated] Couldn't decode ICC.\n"); |
| 383 return 1; |
| 384 } |
| 385 SkDebugf("[terminated] Success! Decoded ICC.\n"); |
| 386 return 0; |
| 387 } |
| 388 |
375 Fuzz::Fuzz(SkData* bytes) : fBytes(SkSafeRef(bytes)), fNextByte(0) {} | 389 Fuzz::Fuzz(SkData* bytes) : fBytes(SkSafeRef(bytes)), fNextByte(0) {} |
376 | 390 |
377 void Fuzz::signalBug () { SkDebugf("Signal bug\n"); raise(SIGSEGV); } | 391 void Fuzz::signalBug () { SkDebugf("Signal bug\n"); raise(SIGSEGV); } |
378 void Fuzz::signalBoring() { SkDebugf("Signal boring\n"); exit(0); } | 392 void Fuzz::signalBoring() { SkDebugf("Signal boring\n"); exit(0); } |
379 | 393 |
380 template <typename T> | 394 template <typename T> |
381 T Fuzz::nextT() { | 395 T Fuzz::nextT() { |
382 if (fNextByte + sizeof(T) > fBytes->size()) { | 396 if (fNextByte + sizeof(T) > fBytes->size()) { |
383 this->signalBoring(); | 397 this->signalBoring(); |
384 } | 398 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
417 if (min > max) { | 431 if (min > max) { |
418 SkDebugf("Check mins and maxes (%f, %f)\n", min, max); | 432 SkDebugf("Check mins and maxes (%f, %f)\n", min, max); |
419 this->signalBoring(); | 433 this->signalBoring(); |
420 } | 434 } |
421 float f = std::abs(this->nextF()); | 435 float f = std::abs(this->nextF()); |
422 if (!std::isnormal(f) && f != 0.0) { | 436 if (!std::isnormal(f) && f != 0.0) { |
423 this->signalBoring(); | 437 this->signalBoring(); |
424 } | 438 } |
425 return min + fmod(f, (max - min + 1)); | 439 return min + fmod(f, (max - min + 1)); |
426 } | 440 } |
OLD | NEW |