diff --git a/tests/Makefile b/tests/Makefile index b1e99ae..1782ea6 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -2,9 +2,11 @@ INCLUDES = -I.. CFLAGS = -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast -DSTB_DIVIDE_TEST CPPFLAGS = -Wno-write-strings -DSTB_DIVIDE_TEST -#CFLAGS += -O -fsanitize=address +# Uncomment this line for reproducing OSS-Fuzz bugs with image_fuzzer +#CFLAGS += -O -fsanitize=address all: $(CC) $(INCLUDES) $(CFLAGS) ../stb_vorbis.c test_c_compilation.c test_c_lexer.c test_dxt.c test_easyfont.c test_image.c test_image_write.c test_perlin.c test_sprintf.c test_truetype.c test_voxel.c -lm $(CC) $(INCLUDES) $(CPPFLAGS) -std=c++0x test_cpp_compilation.cpp -lm -lstdc++ $(CC) $(INCLUDES) $(CFLAGS) -DIWT_TEST image_write_test.c -lm -o image_write_test + $(CC) $(INCLUDES) $(CFLAGS) fuzz_main.c stbi_read_fuzzer.c -lm -o image_fuzzer diff --git a/tests/fuzz_main.c b/tests/fuzz_main.c new file mode 100644 index 0000000..40c0cc8 --- /dev/null +++ b/tests/fuzz_main.c @@ -0,0 +1,54 @@ +#include +#include +#include + +/* fuzz target entry point, works without libFuzzer */ + +int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size); + +int main(int argc, char **argv) +{ + FILE *f; + char *buf = NULL; + long siz_buf; + + if(argc < 2) + { + fprintf(stderr, "no input file\n"); + goto err; + } + + f = fopen(argv[1], "rb"); + if(f == NULL) + { + fprintf(stderr, "error opening input file %s\n", argv[1]); + goto err; + } + + fseek(f, 0, SEEK_END); + + siz_buf = ftell(f); + rewind(f); + + if(siz_buf < 1) goto err; + + buf = (char*)malloc((size_t)siz_buf); + if(buf == NULL) + { + fprintf(stderr, "malloc() failed\n"); + goto err; + } + + if(fread(buf, (size_t)siz_buf, 1, f) != 1) + { + fprintf(stderr, "fread() failed\n"); + goto err; + } + + (void)LLVMFuzzerTestOneInput((uint8_t*)buf, (size_t)siz_buf); + +err: + free(buf); + + return 0; +} diff --git a/tests/ossfuzz.sh b/tests/ossfuzz.sh new file mode 100755 index 0000000..2af98f5 --- /dev/null +++ b/tests/ossfuzz.sh @@ -0,0 +1,25 @@ +#!/bin/bash -eu +# This script is meant to be run by +# https://github.com/google/oss-fuzz/blob/master/projects/stb/Dockerfile + +$CXX $CXXFLAGS -std=c++11 -I. -DSTBI_ONLY_PNG \ + $SRC/stb/tests/stbi_read_fuzzer.c \ + -o $OUT/stb_png_read_fuzzer $LIB_FUZZING_ENGINE + +$CXX $CXXFLAGS -std=c++11 -I. \ + $SRC/stb/tests/stbi_read_fuzzer.c \ + -o $OUT/stbi_read_fuzzer $LIB_FUZZING_ENGINE + +find $SRC/stb/tests/pngsuite -name "*.png" | \ + xargs zip $OUT/stb_png_read_fuzzer_seed_corpus.zip + +cp $SRC/stb/tests/stb_png.dict $OUT/stb_png_read_fuzzer.dict + +tar xvzf $SRC/stb/jpg.tar.gz --directory $SRC/stb/tests +tar xvzf $SRC/stb/gif.tar.gz --directory $SRC/stb/tests + +find $SRC/stb/tests -name "*.png" -o -name "*.jpg" -o -name ".gif" | \ + xargs zip $OUT/stbi_read_fuzzer_seed_corpus.zip + +echo "" >> $SRC/stb/tests/gif.dict +cat $SRC/stb/tests/gif.dict $SRC/stb/tests/stb_png.dict > $OUT/stbi_read_fuzzer.dict diff --git a/tests/stb_png_read_fuzzer.options b/tests/stb_png_read_fuzzer.options deleted file mode 100644 index e0c8a84..0000000 --- a/tests/stb_png_read_fuzzer.options +++ /dev/null @@ -1,2 +0,0 @@ -[libfuzzer] -dict = stb_png.dict diff --git a/tests/stb_png_read_fuzzer.cpp b/tests/stbi_read_fuzzer.c similarity index 73% rename from tests/stb_png_read_fuzzer.cpp rename to tests/stbi_read_fuzzer.c index 0e14e1b..c25398e 100644 --- a/tests/stb_png_read_fuzzer.cpp +++ b/tests/stbi_read_fuzzer.c @@ -1,8 +1,13 @@ +#ifdef __cplusplus +extern "C" { +#endif + #define STB_IMAGE_IMPLEMENTATION -#define STBI_ONLY_PNG + #include "../stb_image.h" -extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) + +int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { int x, y, channels; @@ -17,3 +22,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) return 0; } + +#ifdef __cplusplus +} +#endif \ No newline at end of file