Created
September 21, 2018 09:40
-
-
Save bshastry/7666502bc1fc0513d45f64f6fa3ffc83 to your computer and use it in GitHub Desktop.
snippet of libpng oss-fuzz test harness
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { | |
if (size < kPngHeaderSize) { | |
return 0; | |
} | |
std::vector<unsigned char> v(data, data + size); | |
if (png_sig_cmp(v.data(), 0, kPngHeaderSize)) { | |
// not a PNG. | |
return 0; | |
} | |
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; | |
} | |
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; | |
} | |
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 | |
// Setting up reading from buffer. | |
png_handler.buf_state = new BufState(); | |
png_handler.buf_state->data = data + kPngHeaderSize; | |
png_handler.buf_state->bytes_left = size - kPngHeaderSize; | |
png_set_read_fn(png_handler.png_ptr, png_handler.buf_state, user_read_data); | |
png_set_sig_bytes(png_handler.png_ptr, kPngHeaderSize); | |
if (setjmp(png_jmpbuf(png_handler.png_ptr))) { | |
PNG_CLEANUP | |
return 0; | |
} | |
// Reading. | |
png_read_info(png_handler.png_ptr, png_handler.info_ptr); | |
// reset error handler to put png_deleter into scope. | |
if (setjmp(png_jmpbuf(png_handler.png_ptr))) { | |
PNG_CLEANUP | |
return 0; | |
} | |
png_uint_32 width, height; | |
int bit_depth, color_type, interlace_type, compression_type; | |
int filter_type; | |
if (!png_get_IHDR(png_handler.png_ptr, png_handler.info_ptr, &width, | |
&height, &bit_depth, &color_type, &interlace_type, | |
&compression_type, &filter_type)) { | |
PNG_CLEANUP | |
return 0; | |
} | |
// This is going to be too slow. | |
if (width && height > 100000000 / width) { | |
PNG_CLEANUP | |
return 0; | |
} | |
// Set several transforms that browsers typically use: | |
png_set_gray_to_rgb(png_handler.png_ptr); | |
png_set_expand(png_handler.png_ptr); | |
png_set_packing(png_handler.png_ptr); | |
png_set_scale_16(png_handler.png_ptr); | |
png_set_tRNS_to_alpha(png_handler.png_ptr); | |
int passes = png_set_interlace_handling(png_handler.png_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)); | |
for (int pass = 0; pass < passes; ++pass) { | |
for (png_uint_32 y = 0; y < height; ++y) { | |
png_read_row(png_handler.png_ptr, | |
static_cast<png_bytep>(png_handler.row_ptr), nullptr); | |
} | |
} | |
png_read_end(png_handler.png_ptr, png_handler.end_info_ptr); | |
PNG_CLEANUP | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment