diff --git a/contrib/oss-fuzz/libpng_read_fuzzer.cc b/contrib/oss-fuzz/libpng_read_fuzzer.cc index 0fc9e206c..c1b16249d 100644 --- a/contrib/oss-fuzz/libpng_read_fuzzer.cc +++ b/contrib/oss-fuzz/libpng_read_fuzzer.cc @@ -5,14 +5,13 @@ // Use of this source code is governed by a BSD-style license that may // be found in the LICENSE file https://cs.chromium.org/chromium/src/LICENSE -// Last changed in libpng 1.6.33beta03 [September 27, 2017] +// Last changed in libpng 1.6.32 [August 24, 2017] // The modifications in 2017 by Glenn Randers-Pehrson include // 1. addition of a PNG_CLEANUP macro, // 2. setting the option to ignore ADLER32 checksums, // 3. adding "#include " which is needed on some platforms // to provide memcpy(). -// 4. adding read_end_info() and creating an end_info structure. #include #include @@ -23,6 +22,16 @@ #define PNG_INTERNAL #include "png.h" +#define PNG_CLEANUP \ + if(png_handler.png_ptr) \ + { \ + if (png_handler.info_ptr) \ + png_destroy_read_struct(&png_handler.png_ptr, &png_handler.info_ptr,\ + nullptr); \ + else \ + png_destroy_read_struct(&png_handler.png_ptr, nullptr, nullptr); \ + } + struct BufState { const uint8_t* data; size_t bytes_left; @@ -31,19 +40,16 @@ struct BufState { struct PngObjectHandler { png_infop info_ptr = nullptr; png_structp png_ptr = nullptr; - png_infop end_info_ptr = nullptr; png_voidp row_ptr = nullptr; BufState* buf_state = nullptr; ~PngObjectHandler() { - if (row_ptr) + if (row_ptr && png_ptr) { png_free(png_ptr, row_ptr); - if (end_info_ptr) - png_destroy_read_struct(&png_ptr, &info_ptr, &end_info_ptr); - else if (info_ptr) + } + if (png_ptr && info_ptr) { png_destroy_read_struct(&png_ptr, &info_ptr, nullptr); - else - png_destroy_read_struct(&png_ptr, nullptr, nullptr); + } delete buf_state; } }; @@ -63,7 +69,6 @@ static const int kPngHeaderSize = 8; // Entry point for LibFuzzer. // Roughly follows the libpng book example: // http://www.libpng.org/pub/png/book/chapter13.html - extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { if (size < kPngHeaderSize) { return 0; @@ -76,53 +81,19 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } PngObjectHandler png_handler; - png_handler.png_ptr = nullptr; - png_handler.row_ptr = nullptr; - png_handler.info_ptr = nullptr; - png_handler.end_info_ptr = nullptr; - png_handler.png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); if (!png_handler.png_ptr) { return 0; } -#define PNG_CLEANUP \ - if(png_handler.png_ptr) \ - { \ - if (png_handler.row_ptr) \ - png_free(png_handler.png_ptr, png_handler.row_ptr); \ - if (png_handler.end_info_ptr) \ - png_destroy_read_struct(&png_handler.png_ptr, &png_handler.info_ptr,\ - &png_handler.end_info_ptr); \ - else if (png_handler.info_ptr) \ - png_destroy_read_struct(&png_handler.png_ptr, &png_handler.info_ptr,\ - nullptr); \ - else \ - png_destroy_read_struct(&png_handler.png_ptr, nullptr, nullptr); \ - png_handler.png_ptr = nullptr; \ - png_handler.row_ptr = nullptr; \ - png_handler.info_ptr = nullptr; \ - png_handler.end_info_ptr = nullptr; \ - } - png_handler.info_ptr = png_create_info_struct(png_handler.png_ptr); if (!png_handler.info_ptr) { PNG_CLEANUP return 0; } - png_handler.end_info_ptr = png_create_info_struct(png_handler.png_ptr); - if (!png_handler.end_info_ptr) { - PNG_CLEANUP - return 0; - } - - /* Treat benign errors as warnings */ - png_set_benign_errors(png_handler.png_ptr, 1); - png_set_crc_action(png_handler.png_ptr, PNG_CRC_QUIET_USE, PNG_CRC_QUIET_USE); - #ifdef PNG_IGNORE_ADLER32 png_set_option(png_handler.png_ptr, PNG_IGNORE_ADLER32, PNG_OPTION_ON); #endif @@ -141,7 +112,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { // Reading. png_read_info(png_handler.png_ptr, png_handler.info_ptr); - png_read_update_info(png_handler.png_ptr, png_handler.info_ptr); png_handler.row_ptr = png_malloc( png_handler.png_ptr, png_get_rowbytes(png_handler.png_ptr, png_handler.info_ptr)); @@ -172,7 +142,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { int passes = png_set_interlace_handling(png_handler.png_ptr); png_start_read_image(png_handler.png_ptr); - /* To do: prevent the optimizer from removing this code entirely */ for (int pass = 0; pass < passes; ++pass) { for (png_uint_32 y = 0; y < height; ++y) { png_read_row(png_handler.png_ptr, @@ -180,11 +149,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } } - png_read_end(png_handler.png_ptr, png_handler.end_info_ptr); - PNG_CLEANUP - - /* TO do: exercise the progressive reader here */ - return 0; }