diff options
author | Lode <lvandeve@gmail.com> | 2019-06-30 18:06:48 +0300 |
---|---|---|
committer | Lode <lvandeve@gmail.com> | 2019-07-01 00:33:59 +0300 |
commit | 8f5cc86cde355f55e29790d8ab217e0b1b5fad12 (patch) | |
tree | ee0bf30da32b0da0c9f5c386309b60e212e20940 /lodepng_fuzzer.cpp | |
parent | 430268baa882a707c36b356402b94ab14dc08b69 (diff) |
add a fuzzer for OSS-Fuzz
https://github.com/lvandeve/lodepng/issues/90
Diffstat (limited to 'lodepng_fuzzer.cpp')
-rw-r--r-- | lodepng_fuzzer.cpp | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/lodepng_fuzzer.cpp b/lodepng_fuzzer.cpp new file mode 100644 index 0000000..c9fb701 --- /dev/null +++ b/lodepng_fuzzer.cpp @@ -0,0 +1,94 @@ +/* +LodePNG Fuzzer + +Copyright (c) 2005-2019 Lode Vandevenne + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*/ + +// clang++ -fsanitize=fuzzer lodepng.cpp lodepng_fuzzer.cpp -O3 && ./a.out + +#include "lodepng.h" + +#include <cstdint> + +namespace { +// Amount of valid colortype/bidthdepth combinations in the PNG file format. +const size_t num_combinations = 15; + +LodePNGColorType colortypes[num_combinations] = { + LCT_GREY, LCT_GREY, LCT_GREY, LCT_GREY, LCT_GREY, // 1, 2, 4, 8 or 16 bits + LCT_RGB, LCT_RGB, // 8 or 16 bits + LCT_PALETTE, LCT_PALETTE, LCT_PALETTE, LCT_PALETTE, // 1, 2, 4 or 8 bits + LCT_GREY_ALPHA, LCT_GREY_ALPHA, // 8 or 16 bits + LCT_RGBA, LCT_RGBA, // 8 or 16 bits +}; + +unsigned bitdepths[num_combinations] = { + 1, 2, 4, 8, 16, // gray + 8, 16, // rgb + 1, 2, 4, 8, // palette + 8, 16, // gray+alpha + 8, 16, // rgb+alpha +}; + +unsigned testDecode(lodepng::State& state, const uint8_t* data, size_t size) { + unsigned w, h; + std::vector<unsigned char> image; + return lodepng::decode(image, w, h, state, (const unsigned char*)data, size); +} +} // end anonymous namespace + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + if(size == 0) return 0; + size_t random_color_type = data[0] % num_combinations; + data++; + size--; + + lodepng::State state; + + // Make the decoder ignore three types of checksums the PNG/zlib format have + // built-in, because they are less likely to be correct in the random input + // data, and if invalid make the decoder return an error before much gets ran. + state.decoder.zlibsettings.ignore_adler32 = 1; + state.decoder.zlibsettings.ignore_nlen = 1; + state.decoder.ignore_crc = 1; + // Also make decoder attempt to support partial files with missing ending to + // go further with parsing. + state.decoder.ignore_end = 1; + + // First test without color conversion (keep color type of the PNG) + state.decoder.color_convert = 0; + + unsigned error = testDecode(state, data, size); + + // If valid PNG found, try decoding with color conversion to the most common + // default color type, and to the randomly chosen type. + if(error == 0) { + state.decoder.color_convert = 1; + testDecode(state, data, size); + + state.info_raw.colortype = colortypes[random_color_type]; + state.info_raw.bitdepth = bitdepths[random_color_type]; + testDecode(state, data, size); + } + + return 0; +} |