| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <stddef.h> | 5 #include <stddef.h> |
| 6 #include <stdint.h> | 6 #include <stdint.h> |
| 7 | 7 |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/callback_helpers.h" | 11 #include "base/callback_helpers.h" |
| 12 #define PNG_INTERNAL | 12 #define PNG_INTERNAL |
| 13 #include "third_party/libpng/png.h" | 13 #include "third_party/libpng/png.h" |
| 14 | 14 |
| 15 #ifndef PNG_FUZZ_PROGRESSIVE |
| 16 |
| 17 // Read sequentially, with png_read_row. |
| 15 struct BufState { | 18 struct BufState { |
| 16 const uint8_t* data; | 19 const uint8_t* data; |
| 17 size_t bytes_left; | 20 size_t bytes_left; |
| 18 }; | 21 }; |
| 19 | 22 |
| 20 void user_read_data(png_structp png_ptr, png_bytep data, png_size_t length) { | 23 void user_read_data(png_structp png_ptr, png_bytep data, png_size_t length) { |
| 21 BufState* buf_state = static_cast<BufState*>(png_get_io_ptr(png_ptr)); | 24 BufState* buf_state = static_cast<BufState*>(png_get_io_ptr(png_ptr)); |
| 22 if (length > buf_state->bytes_left) { | 25 if (length > buf_state->bytes_left) { |
| 23 png_error(png_ptr, "read error"); | 26 png_error(png_ptr, "read error"); |
| 24 } | 27 } |
| 25 memcpy(data, buf_state->data, length); | 28 memcpy(data, buf_state->data, length); |
| 26 buf_state->bytes_left -= length; | 29 buf_state->bytes_left -= length; |
| 27 buf_state->data += length; | 30 buf_state->data += length; |
| 28 } | 31 } |
| 32 |
| 33 #endif // PNG_FUZZ_PROGRESSIVE |
| 34 |
| 29 static const int kPngHeaderSize = 8; | 35 static const int kPngHeaderSize = 8; |
| 30 | 36 |
| 31 // Entry point for LibFuzzer. | 37 // Entry point for LibFuzzer. |
| 32 // Roughly follows the libpng book example: | 38 // Roughly follows the libpng book example: |
| 33 // http://www.libpng.org/pub/png/book/chapter13.html | 39 // http://www.libpng.org/pub/png/book/chapter13.html |
| 34 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { | 40 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { |
| 35 if (size < kPngHeaderSize) { | 41 if (size < kPngHeaderSize) { |
| 36 return 0; | 42 return 0; |
| 37 } | 43 } |
| 38 | 44 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 53 #endif | 59 #endif |
| 54 | 60 |
| 55 png_set_crc_action(png_ptr, PNG_CRC_QUIET_USE, PNG_CRC_QUIET_USE); | 61 png_set_crc_action(png_ptr, PNG_CRC_QUIET_USE, PNG_CRC_QUIET_USE); |
| 56 | 62 |
| 57 png_infop info_ptr = png_create_info_struct(png_ptr); | 63 png_infop info_ptr = png_create_info_struct(png_ptr); |
| 58 assert(info_ptr); | 64 assert(info_ptr); |
| 59 | 65 |
| 60 base::ScopedClosureRunner struct_deleter(base::Bind( | 66 base::ScopedClosureRunner struct_deleter(base::Bind( |
| 61 &png_destroy_read_struct, &png_ptr, &info_ptr, nullptr)); | 67 &png_destroy_read_struct, &png_ptr, &info_ptr, nullptr)); |
| 62 | 68 |
| 69 #ifdef PNG_FUZZ_PROGRESSIVE |
| 70 png_set_progressive_read_fn(png_ptr, nullptr, nullptr, nullptr, nullptr); |
| 71 png_process_data(png_ptr, info_ptr, const_cast<uint8_t*>(data), size); |
| 72 #else |
| 63 // Setting up reading from buffer. | 73 // Setting up reading from buffer. |
| 64 std::unique_ptr<BufState> buf_state(new BufState()); | 74 std::unique_ptr<BufState> buf_state(new BufState()); |
| 65 buf_state->data = data + kPngHeaderSize; | 75 buf_state->data = data + kPngHeaderSize; |
| 66 buf_state->bytes_left = size - kPngHeaderSize; | 76 buf_state->bytes_left = size - kPngHeaderSize; |
| 67 png_set_read_fn(png_ptr, buf_state.get(), user_read_data); | 77 png_set_read_fn(png_ptr, buf_state.get(), user_read_data); |
| 68 png_set_sig_bytes(png_ptr, kPngHeaderSize); | 78 png_set_sig_bytes(png_ptr, kPngHeaderSize); |
| 69 | 79 |
| 70 // libpng error handling. | 80 // libpng error handling. |
| 71 if (setjmp(png_jmpbuf(png_ptr))) { | 81 if (setjmp(png_jmpbuf(png_ptr))) { |
| 72 return 0; | 82 return 0; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 98 return 0; | 108 return 0; |
| 99 | 109 |
| 100 int passes = png_set_interlace_handling(png_ptr); | 110 int passes = png_set_interlace_handling(png_ptr); |
| 101 png_start_read_image(png_ptr); | 111 png_start_read_image(png_ptr); |
| 102 | 112 |
| 103 for (int pass = 0; pass < passes; ++pass) { | 113 for (int pass = 0; pass < passes; ++pass) { |
| 104 for (png_uint_32 y = 0; y < height; ++y) { | 114 for (png_uint_32 y = 0; y < height; ++y) { |
| 105 png_read_row(png_ptr, static_cast<png_bytep>(row), NULL); | 115 png_read_row(png_ptr, static_cast<png_bytep>(row), NULL); |
| 106 } | 116 } |
| 107 } | 117 } |
| 118 #endif // PNG_FUZZ_PROGRESSIVE |
| 108 | 119 |
| 109 return 0; | 120 return 0; |
| 110 } | 121 } |
| OLD | NEW |