diff --git a/contrib/oss-fuzz/tiff_read_rgba_fuzzer.cc b/contrib/oss-fuzz/tiff_read_rgba_fuzzer.cc index ec1c9b63..dd17b5d8 100644 --- a/contrib/oss-fuzz/tiff_read_rgba_fuzzer.cc +++ b/contrib/oss-fuzz/tiff_read_rgba_fuzzer.cc @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -39,8 +40,10 @@ extern "C" void handle_error(const char *unused, const char *unused2, va_list un } extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { +#ifndef STANDALONE TIFFSetErrorHandler(handle_error); TIFFSetWarningHandler(handle_error); +#endif #if defined(__has_feature) # if __has_feature(memory_sanitizer) // libjpeg-turbo has issues with MSAN and SIMD code @@ -95,3 +98,82 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { return 0; } + +#ifdef STANDALONE + +template static void CPL_IGNORE_RET_VAL(T) {} + +static void Usage(int, char* argv[]) +{ + fprintf(stderr, "%s [--help] [-repeat N] filename.\n", argv[0]); + exit(1); +} + +int main(int argc, char* argv[]) +{ + int nRet = 0; + void* buf = NULL; + int nLen = 0; + int nLoops = 1; + const char* pszFilename = NULL; + + for(int i = 1; i < argc; i++ ) + { + if( i + 1 < argc && strcmp(argv[i], "-repeat") == 0 ) + { + nLoops = atoi(argv[i+1]); + i++; + } + else if( strcmp(argv[i], "-dummy") == 0 ) + { + uint8_t dummy = ' '; + return LLVMFuzzerTestOneInput(&dummy, 1); + } + else if( strcmp(argv[i], "--help") == 0 ) + { + Usage(argc, argv); + } + else if( argv[i][0] == '-' ) + { + fprintf(stderr, "Unrecognized option: %s", argv[i]); + Usage(argc, argv); + } + else + { + pszFilename = argv[i]; + } + } + if( pszFilename == nullptr ) + { + fprintf(stderr, "No filename specified\n"); + Usage(argc, argv); + } + FILE* f = fopen(pszFilename, "rb"); + if( !f ) + { + fprintf(stderr, "%s does not exist.\n", pszFilename); + exit(1); + } + fseek(f, 0, SEEK_END); + nLen = (int)ftell(f); + fseek(f, 0, SEEK_SET); + buf = malloc(nLen); + if( !buf ) + { + fprintf(stderr, "malloc failed.\n"); + fclose(f); + exit(1); + } + CPL_IGNORE_RET_VAL(fread(buf, nLen, 1, f)); + fclose(f); + for( int i = 0; i < nLoops; i++ ) + { + nRet = LLVMFuzzerTestOneInput(static_cast(buf), nLen); + if( nRet != 0 ) + break; + } + free(buf); + return nRet; +} + +#endif