diff --git a/CMakeLists.txt b/CMakeLists.txt index 226d1e5..f7bab9b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -275,10 +275,15 @@ cliprogram(penrose-vector-test penrose.c COMPILE_DEFINITIONS TEST_VECTORS) cliprogram(sort-test sort.c COMPILE_DEFINITIONS SORT_TEST) cliprogram(tree234-test tree234.c COMPILE_DEFINITIONS TEST) -write_generated_games_header() -cliprogram(fuzzpuzz fuzzpuzz.c list.c ${puzzle_sources} - COMPILE_DEFINITIONS COMBINED) if(build_cli_programs) + write_generated_games_header() + include(CheckFunctionExists) + check_function_exists(HF_ITER HAVE_HF_ITER) + if(HAVE_HF_ITER) + add_definitions(-DHAVE_HF_ITER) + endif() + cliprogram(fuzzpuzz fuzzpuzz.c list.c ${puzzle_sources} + COMPILE_DEFINITIONS COMBINED) target_include_directories(fuzzpuzz PRIVATE ${generated_include_dir}) endif() diff --git a/fuzzpuzz.c b/fuzzpuzz.c index 034421d..f4f3b92 100644 --- a/fuzzpuzz.c +++ b/fuzzpuzz.c @@ -16,6 +16,13 @@ * cmake --build build-afl --target fuzzpuzz * mkdir fuzz-in && ln icons/''*.sav fuzz-in * afl-fuzz -i fuzz-in -o fuzz-out -x fuzzpuzz.dict -- build-afl/fuzzpuzz + * + * Similarly with Honggfuzz: + * + * CC=hfuzz-cc cmake -B build-honggfuzz + * cmake --build build-honggfuzz --target fuzzpuzz + * mkdir fuzz-corpus && ln icons/''*.sav fuzz-corpus + * honggfuzz -s -i fuzz-corpus -w fuzzpuzz.dict -- build-honggfuzz/fuzzpuzz */ #include @@ -32,6 +39,10 @@ __AFL_FUZZ_INIT(); #endif +#ifdef HAVE_HF_ITER +extern int HF_ITER(unsigned char **, size_t *); +#endif + static const char *fuzz_one(bool (*readfn)(void *, void *, int), void *rctx, void (*rewindfn)(void *), void (*writefn)(void *, const void *, int), @@ -123,6 +134,22 @@ int main(int argc, char **argv) ret = 1; continue; } +#elif defined(HAVE_HF_ITER) + /* + * Honggfuzz persistent mode. Unlike AFL persistent mode, the + * resulting executable cannot be run outside of Honggfuzz. + */ + while (true) { + unsigned char *testcase_buf; + size_t testcase_len; + if (in != NULL) fclose(in); + HF_ITER(&testcase_buf, &testcase_len); + in = fmemopen(testcase_buf, testcase_len, "r"); + if (in == NULL) { + fprintf(stderr, "fmemopen failed"); + ret = 1; + continue; + } #else in = stdin; while (ret == -1) {