From 9e500b49ace31f53cab94ca426cde5998b3b91fd Mon Sep 17 00:00:00 2001 From: Michael Macnair Date: Fri, 12 Feb 2016 09:35:08 +0000 Subject: [PATCH] Add support for afl-fuzz testing "make fuzz" creates a simple executable that de-serialises stdin and re-serialises to stdout. "make fuzz_testcases" extracts the smaller json test cases into a testcases directory. The library can then be fuzzed as follows: CC=afl-clang-fast make fuzz make fuzz_testcases mkdir out afl-fuzz -i testcases -o out ./fuzz --- Makefile | 14 ++++++++++++-- test/fuzz.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 test/fuzz.cpp diff --git a/Makefile b/Makefile index fdef784083..ddb73f259e 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ all: json_unit # clean up clean: - rm -f json_unit json_benchmarks + rm -f json_unit json_benchmarks fuzz ########################################################################## @@ -24,6 +24,16 @@ json_unit: test/unit.cpp src/json.hpp test/catch.hpp $(CXX) -std=c++11 $(CXXFLAGS) $(FLAGS) $(CPPFLAGS) -I src -I test $< $(LDFLAGS) -o $@ +########################################################################## +# fuzzing +########################################################################## + +fuzz: test/fuzz.cpp src/json.hpp + $(CXX) -std=c++11 $(CXXFLAGS) $(FLAGS) $(CPPFLAGS) -I src -I test $< $(LDFLAGS) -lstdc++ -lm -o $@ +fuzz_testcases: + mkdir -p testcases && find test/ -size -5k -name *json | xargs -I{} cp "{}" testcases + @echo "Test cases suitable for fuzzing have been copied into the testcases directory" + ########################################################################## # static analyzer ########################################################################## @@ -48,7 +58,7 @@ pretty: --indent-col1-comments --pad-oper --pad-header --align-pointer=type \ --align-reference=type --add-brackets --convert-tabs --close-templates \ --lineend=linux --preserve-date --suffix=none \ - src/json.hpp src/json.hpp.re2c test/unit.cpp benchmarks/benchmarks.cpp doc/examples/*.cpp + src/json.hpp src/json.hpp.re2c test/unit.cpp test/fuzz.cpp benchmarks/benchmarks.cpp doc/examples/*.cpp ########################################################################## diff --git a/test/fuzz.cpp b/test/fuzz.cpp new file mode 100644 index 0000000000..1671de5ec9 --- /dev/null +++ b/test/fuzz.cpp @@ -0,0 +1,42 @@ +/* + __ _____ _____ _____ + __| | __| | | | JSON for Modern C++ (fuzz test support) +| | |__ | | | | | | version 2.0.0 +|_____|_____|_____|_|___| https://github.com/nlohmann/json + +To run under afl: + afl-fuzz -i testcases -o output ./fuzz + +Licensed under the MIT License . +*/ + +#include + +using json = nlohmann::json; + +int main() +{ + json *jp; + +#ifdef __AFL_HAVE_MANUAL_CONTROL + while (__AFL_LOOP(1000)) { +#endif + jp = new json(); + json j = *jp; + try { + j << std::cin; + } catch (std::invalid_argument e) { + std::cout << "Invalid argument in parsing" << e.what() << '\n'; + } + + if (j.find("foo") != j.end()) { + std::cout << "Found a foo"; + } + + std::cout << j.type() << j << std::endl; + + delete jp; +#ifdef __AFL_HAVE_MANUAL_CONTROL + } +#endif +}