diff --git a/fuzzing/CMakeLists.txt b/fuzzing/CMakeLists.txt index fdd7126..84278e8 100644 --- a/fuzzing/CMakeLists.txt +++ b/fuzzing/CMakeLists.txt @@ -26,3 +26,8 @@ if (ENABLE_FUZZING) endif() + +if(ENABLE_CJSON_TEST) + ADD_EXECUTABLE(fuzz_main fuzz_main.c) + TARGET_LINK_LIBRARIES(fuzz_main cjson) +endif() \ No newline at end of file diff --git a/fuzzing/cjson_read_fuzzer.cc b/fuzzing/cjson_read_fuzzer.cc index 3b76894..4ec4322 100644 --- a/fuzzing/cjson_read_fuzzer.cc +++ b/fuzzing/cjson_read_fuzzer.cc @@ -4,9 +4,17 @@ #include "../cJSON.h" -extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) +#ifdef __cplusplus +extern "C" +#endif +int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + cJSON *json; size_t offset = 4; + unsigned char *copied; + char *printed_json = NULL; + int minify, require_termination, formatted, buffered; + if(size <= offset) return 0; if(data[0] != '1' && data[0] != '0') return 0; @@ -14,18 +22,18 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) if(data[2] != '1' && data[2] != '0') return 0; if(data[3] != '1' && data[3] != '0') return 0; - int minify = data[0] == '1' ? 1 : 0; - int require_termination = data[1] == '1' ? 1 : 0; - int formatted = data[2] == '1' ? 1 : 0; - int buffered = data[3] == '1' ? 1 : 0; + minify = data[0] == '1' ? 1 : 0; + require_termination = data[1] == '1' ? 1 : 0; + formatted = data[2] == '1' ? 1 : 0; + buffered = data[3] == '1' ? 1 : 0; - unsigned char *copied = (unsigned char*)malloc(size); + copied = (unsigned char*)malloc(size); if(copied == NULL) return 0; memcpy(copied, data, size); copied[size-1] = '\0'; - cJSON *json = cJSON_ParseWithOpts((const char*)copied + offset, NULL, require_termination); + json = cJSON_ParseWithOpts((const char*)copied + offset, NULL, require_termination); if(json == NULL) { @@ -33,8 +41,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) return 0; } - char *printed_json = NULL; - if(buffered) { printed_json = cJSON_PrintBuffered(json, 1, formatted); diff --git a/fuzzing/fuzz_main.c b/fuzzing/fuzz_main.c new file mode 100644 index 0000000..e004115 --- /dev/null +++ b/fuzzing/fuzz_main.c @@ -0,0 +1,56 @@ +#include +#include +#include + +int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size); /* required by C90 */ + +#include "cjson_read_fuzzer.cc" + +/* fuzz target entry point, works without libFuzzer */ + +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; +}