From f829e72bd08d8d96ddbef2a91ed24791d8389563 Mon Sep 17 00:00:00 2001 From: Tanuj Garg Date: Fri, 29 May 2020 00:58:22 +0530 Subject: [PATCH 01/26] [Experiment] added a test fuzzer --- test/src/fuzzer-temp.cpp | 73 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 test/src/fuzzer-temp.cpp diff --git a/test/src/fuzzer-temp.cpp b/test/src/fuzzer-temp.cpp new file mode 100644 index 0000000000..b1b25d84d8 --- /dev/null +++ b/test/src/fuzzer-temp.cpp @@ -0,0 +1,73 @@ +/* + __ _____ _____ _____ + __| | __| | | | JSON for Modern C++ (fuzz test support) +| | |__ | | | | | | version 3.7.3 +|_____|_____|_____|_|___| https://github.com/nlohmann/json + +This file implements a parser test suitable for fuzz testing. Given a byte +array data, it performs the following steps: + +- j1 = from_bson(data) +- vec = to_bson(j1) +- j2 = from_bson(vec) +- assert(j1 == j2) + +The provided function `LLVMFuzzerTestOneInput` can be used in different fuzzer +drivers. + +Licensed under the MIT License . +*/ + +#include +#include +#include + +using json = nlohmann::json; + +// see http://llvm.org/docs/LibFuzzer.html +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) +{ + try + { + // step 1: parse input + std::vector vec1(data, data + size); + json j1 = json::from_bson(vec1); + + if (j1.is_discarded()) + { + return 0; + } + + try + { + // step 2: round trip + std::vector vec2 = json::to_bson(j1); + + // parse serialization + json j2 = json::from_bson(vec2); + + // serializations must match + assert(json::to_bson(j2) == vec2); + } + catch (const json::parse_error&) + { + // parsing a BSON serialization must not fail + assert(false); + } + } + catch (const json::parse_error&) + { + // parse errors are ok, because input may be random bytes + } + catch (const json::type_error&) + { + // type errors can occur during parsing, too + } + catch (const json::out_of_range&) + { + // out of range errors can occur during parsing, too + } + + // return 0 - non-zero return values are reserved for future use + return 0; +} From cd36c9b5571b667de0487ec38678819fe39a6603 Mon Sep 17 00:00:00 2001 From: Tanuj Garg Date: Fri, 29 May 2020 01:05:25 +0530 Subject: [PATCH 02/26] [Experiment] edited makefiles to include test fuzzer --- Makefile | 8 ++++++++ test/Makefile | 5 ++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 08c40d2f34..931e1899e3 100644 --- a/Makefile +++ b/Makefile @@ -402,6 +402,14 @@ fuzz_testing_ubjson: find test/data -size -5k -name *.ubjson | xargs -I{} cp "{}" fuzz-testing/testcases @echo "Execute: afl-fuzz -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer" +fuzz_testing_bson: + rm -fr fuzz-testing + mkdir -p fuzz-testing fuzz-testing/testcases fuzz-testing/out + $(MAKE) temp_fuzzer -C test CXX=afl-clang++ + mv test/temp_fuzzer fuzz-testing/fuzzer + find test/data -size -5k -name *.bson | xargs -I{} cp "{}" fuzz-testing/testcases + @echo "Execute: afl-fuzz -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer" + fuzzing-start: afl-fuzz -S fuzzer1 -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer > /dev/null & afl-fuzz -S fuzzer2 -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer > /dev/null & diff --git a/test/Makefile b/test/Makefile index 7bf0fef98b..9b8150b51b 100644 --- a/test/Makefile +++ b/test/Makefile @@ -94,7 +94,7 @@ check: $(OBJECTS) $(TESTCASES) ############################################################################## FUZZER_ENGINE = src/fuzzer-driver_afl.cpp -FUZZERS = parse_afl_fuzzer parse_bson_fuzzer parse_cbor_fuzzer parse_msgpack_fuzzer parse_ubjson_fuzzer +FUZZERS = parse_afl_fuzzer parse_bson_fuzzer parse_cbor_fuzzer parse_msgpack_fuzzer parse_ubjson_fuzzer temp_fuzzer fuzzers: $(FUZZERS) parse_afl_fuzzer: @@ -111,3 +111,6 @@ parse_msgpack_fuzzer: parse_ubjson_fuzzer: $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(FUZZER_ENGINE) src/fuzzer-parse_ubjson.cpp -o $@ + +temp_fuzzer: + $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(FUZZER_ENGINE) src/fuzzer-temp.cpp -o $@ From a90ff95ab5611fec2a808ba51170d072318855fc Mon Sep 17 00:00:00 2001 From: Tanuj Garg Date: Fri, 29 May 2020 01:08:36 +0530 Subject: [PATCH 03/26] [Experiment] corrected a typo in makefile --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 931e1899e3..4e784c4283 100644 --- a/Makefile +++ b/Makefile @@ -402,7 +402,7 @@ fuzz_testing_ubjson: find test/data -size -5k -name *.ubjson | xargs -I{} cp "{}" fuzz-testing/testcases @echo "Execute: afl-fuzz -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer" -fuzz_testing_bson: +fuzz_testing_temp: rm -fr fuzz-testing mkdir -p fuzz-testing fuzz-testing/testcases fuzz-testing/out $(MAKE) temp_fuzzer -C test CXX=afl-clang++ From b95ca37affccedb742374ab4406b152866c8fe7e Mon Sep 17 00:00:00 2001 From: Tanuj Garg Date: Fri, 29 May 2020 01:44:30 +0530 Subject: [PATCH 04/26] [Experiment] changed name of test fuzzer --- Makefile | 7 ++-- test/Makefile | 6 +-- test/src/fuzzer-parse_bson2.cpp | 73 +++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 6 deletions(-) create mode 100644 test/src/fuzzer-parse_bson2.cpp diff --git a/Makefile b/Makefile index 4e784c4283..0e43dd934b 100644 --- a/Makefile +++ b/Makefile @@ -44,6 +44,7 @@ all: @echo "fuzz_testing_cbor - prepare fuzz testing of the CBOR parser" @echo "fuzz_testing_msgpack - prepare fuzz testing of the MessagePack parser" @echo "fuzz_testing_ubjson - prepare fuzz testing of the UBJSON parser" + @echo "fuzz_testing_bson2 - prepare fuzz testing of the BSON2 parser" @echo "json_unit - create single-file test executable" @echo "pedantic_clang - run Clang with maximal warning flags" @echo "pedantic_gcc - run GCC with maximal warning flags" @@ -402,11 +403,11 @@ fuzz_testing_ubjson: find test/data -size -5k -name *.ubjson | xargs -I{} cp "{}" fuzz-testing/testcases @echo "Execute: afl-fuzz -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer" -fuzz_testing_temp: +fuzz_testing_bson2: rm -fr fuzz-testing mkdir -p fuzz-testing fuzz-testing/testcases fuzz-testing/out - $(MAKE) temp_fuzzer -C test CXX=afl-clang++ - mv test/temp_fuzzer fuzz-testing/fuzzer + $(MAKE) parse_bson2_fuzzer -C test CXX=afl-clang++ + mv test/parse_bson2_fuzzer fuzz-testing/fuzzer find test/data -size -5k -name *.bson | xargs -I{} cp "{}" fuzz-testing/testcases @echo "Execute: afl-fuzz -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer" diff --git a/test/Makefile b/test/Makefile index 9b8150b51b..83053d9cd1 100644 --- a/test/Makefile +++ b/test/Makefile @@ -94,7 +94,7 @@ check: $(OBJECTS) $(TESTCASES) ############################################################################## FUZZER_ENGINE = src/fuzzer-driver_afl.cpp -FUZZERS = parse_afl_fuzzer parse_bson_fuzzer parse_cbor_fuzzer parse_msgpack_fuzzer parse_ubjson_fuzzer temp_fuzzer +FUZZERS = parse_afl_fuzzer parse_bson_fuzzer parse_cbor_fuzzer parse_msgpack_fuzzer parse_ubjson_fuzzer parse_bson2_fuzzer fuzzers: $(FUZZERS) parse_afl_fuzzer: @@ -112,5 +112,5 @@ parse_msgpack_fuzzer: parse_ubjson_fuzzer: $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(FUZZER_ENGINE) src/fuzzer-parse_ubjson.cpp -o $@ -temp_fuzzer: - $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(FUZZER_ENGINE) src/fuzzer-temp.cpp -o $@ +parse_bson2_fuzzer: + $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(FUZZER_ENGINE) src/fuzzer-parse_bson2.cpp -o $@ diff --git a/test/src/fuzzer-parse_bson2.cpp b/test/src/fuzzer-parse_bson2.cpp new file mode 100644 index 0000000000..b1b25d84d8 --- /dev/null +++ b/test/src/fuzzer-parse_bson2.cpp @@ -0,0 +1,73 @@ +/* + __ _____ _____ _____ + __| | __| | | | JSON for Modern C++ (fuzz test support) +| | |__ | | | | | | version 3.7.3 +|_____|_____|_____|_|___| https://github.com/nlohmann/json + +This file implements a parser test suitable for fuzz testing. Given a byte +array data, it performs the following steps: + +- j1 = from_bson(data) +- vec = to_bson(j1) +- j2 = from_bson(vec) +- assert(j1 == j2) + +The provided function `LLVMFuzzerTestOneInput` can be used in different fuzzer +drivers. + +Licensed under the MIT License . +*/ + +#include +#include +#include + +using json = nlohmann::json; + +// see http://llvm.org/docs/LibFuzzer.html +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) +{ + try + { + // step 1: parse input + std::vector vec1(data, data + size); + json j1 = json::from_bson(vec1); + + if (j1.is_discarded()) + { + return 0; + } + + try + { + // step 2: round trip + std::vector vec2 = json::to_bson(j1); + + // parse serialization + json j2 = json::from_bson(vec2); + + // serializations must match + assert(json::to_bson(j2) == vec2); + } + catch (const json::parse_error&) + { + // parsing a BSON serialization must not fail + assert(false); + } + } + catch (const json::parse_error&) + { + // parse errors are ok, because input may be random bytes + } + catch (const json::type_error&) + { + // type errors can occur during parsing, too + } + catch (const json::out_of_range&) + { + // out of range errors can occur during parsing, too + } + + // return 0 - non-zero return values are reserved for future use + return 0; +} From 651fb03be06eea7b394d8e2c7d1567cfe2a7a838 Mon Sep 17 00:00:00 2001 From: Tanuj Garg Date: Fri, 29 May 2020 01:50:55 +0530 Subject: [PATCH 05/26] [Experiment] renamed again for confirmation --- Makefile | 8 ++-- test/Makefile | 6 +-- test/src/fuzzer-parse_bson2.cpp | 73 --------------------------------- 3 files changed, 7 insertions(+), 80 deletions(-) delete mode 100644 test/src/fuzzer-parse_bson2.cpp diff --git a/Makefile b/Makefile index 0e43dd934b..8f35dbdf21 100644 --- a/Makefile +++ b/Makefile @@ -44,7 +44,7 @@ all: @echo "fuzz_testing_cbor - prepare fuzz testing of the CBOR parser" @echo "fuzz_testing_msgpack - prepare fuzz testing of the MessagePack parser" @echo "fuzz_testing_ubjson - prepare fuzz testing of the UBJSON parser" - @echo "fuzz_testing_bson2 - prepare fuzz testing of the BSON2 parser" + @echo "fuzz_testing_temp - prepare fuzz testing of the temp" @echo "json_unit - create single-file test executable" @echo "pedantic_clang - run Clang with maximal warning flags" @echo "pedantic_gcc - run GCC with maximal warning flags" @@ -403,11 +403,11 @@ fuzz_testing_ubjson: find test/data -size -5k -name *.ubjson | xargs -I{} cp "{}" fuzz-testing/testcases @echo "Execute: afl-fuzz -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer" -fuzz_testing_bson2: +fuzz_testing_temp: rm -fr fuzz-testing mkdir -p fuzz-testing fuzz-testing/testcases fuzz-testing/out - $(MAKE) parse_bson2_fuzzer -C test CXX=afl-clang++ - mv test/parse_bson2_fuzzer fuzz-testing/fuzzer + $(MAKE) temp_fuzzer -C test CXX=afl-clang++ + mv test/temp_fuzzer fuzz-testing/fuzzer find test/data -size -5k -name *.bson | xargs -I{} cp "{}" fuzz-testing/testcases @echo "Execute: afl-fuzz -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer" diff --git a/test/Makefile b/test/Makefile index 83053d9cd1..9b8150b51b 100644 --- a/test/Makefile +++ b/test/Makefile @@ -94,7 +94,7 @@ check: $(OBJECTS) $(TESTCASES) ############################################################################## FUZZER_ENGINE = src/fuzzer-driver_afl.cpp -FUZZERS = parse_afl_fuzzer parse_bson_fuzzer parse_cbor_fuzzer parse_msgpack_fuzzer parse_ubjson_fuzzer parse_bson2_fuzzer +FUZZERS = parse_afl_fuzzer parse_bson_fuzzer parse_cbor_fuzzer parse_msgpack_fuzzer parse_ubjson_fuzzer temp_fuzzer fuzzers: $(FUZZERS) parse_afl_fuzzer: @@ -112,5 +112,5 @@ parse_msgpack_fuzzer: parse_ubjson_fuzzer: $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(FUZZER_ENGINE) src/fuzzer-parse_ubjson.cpp -o $@ -parse_bson2_fuzzer: - $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(FUZZER_ENGINE) src/fuzzer-parse_bson2.cpp -o $@ +temp_fuzzer: + $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(FUZZER_ENGINE) src/fuzzer-temp.cpp -o $@ diff --git a/test/src/fuzzer-parse_bson2.cpp b/test/src/fuzzer-parse_bson2.cpp deleted file mode 100644 index b1b25d84d8..0000000000 --- a/test/src/fuzzer-parse_bson2.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/* - __ _____ _____ _____ - __| | __| | | | JSON for Modern C++ (fuzz test support) -| | |__ | | | | | | version 3.7.3 -|_____|_____|_____|_|___| https://github.com/nlohmann/json - -This file implements a parser test suitable for fuzz testing. Given a byte -array data, it performs the following steps: - -- j1 = from_bson(data) -- vec = to_bson(j1) -- j2 = from_bson(vec) -- assert(j1 == j2) - -The provided function `LLVMFuzzerTestOneInput` can be used in different fuzzer -drivers. - -Licensed under the MIT License . -*/ - -#include -#include -#include - -using json = nlohmann::json; - -// see http://llvm.org/docs/LibFuzzer.html -extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) -{ - try - { - // step 1: parse input - std::vector vec1(data, data + size); - json j1 = json::from_bson(vec1); - - if (j1.is_discarded()) - { - return 0; - } - - try - { - // step 2: round trip - std::vector vec2 = json::to_bson(j1); - - // parse serialization - json j2 = json::from_bson(vec2); - - // serializations must match - assert(json::to_bson(j2) == vec2); - } - catch (const json::parse_error&) - { - // parsing a BSON serialization must not fail - assert(false); - } - } - catch (const json::parse_error&) - { - // parse errors are ok, because input may be random bytes - } - catch (const json::type_error&) - { - // type errors can occur during parsing, too - } - catch (const json::out_of_range&) - { - // out of range errors can occur during parsing, too - } - - // return 0 - non-zero return values are reserved for future use - return 0; -} From def05d0ad12e8145437a29b90a9b48011ec4f401 Mon Sep 17 00:00:00 2001 From: Tanuj Garg Date: Fri, 29 May 2020 22:35:31 +0530 Subject: [PATCH 06/26] [Experiment] temp fuzzer removed --- Makefile | 9 ----- test/Makefile | 4 +-- test/src/fuzzer-temp.cpp | 73 ---------------------------------------- 3 files changed, 1 insertion(+), 85 deletions(-) delete mode 100644 test/src/fuzzer-temp.cpp diff --git a/Makefile b/Makefile index 8f35dbdf21..08c40d2f34 100644 --- a/Makefile +++ b/Makefile @@ -44,7 +44,6 @@ all: @echo "fuzz_testing_cbor - prepare fuzz testing of the CBOR parser" @echo "fuzz_testing_msgpack - prepare fuzz testing of the MessagePack parser" @echo "fuzz_testing_ubjson - prepare fuzz testing of the UBJSON parser" - @echo "fuzz_testing_temp - prepare fuzz testing of the temp" @echo "json_unit - create single-file test executable" @echo "pedantic_clang - run Clang with maximal warning flags" @echo "pedantic_gcc - run GCC with maximal warning flags" @@ -403,14 +402,6 @@ fuzz_testing_ubjson: find test/data -size -5k -name *.ubjson | xargs -I{} cp "{}" fuzz-testing/testcases @echo "Execute: afl-fuzz -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer" -fuzz_testing_temp: - rm -fr fuzz-testing - mkdir -p fuzz-testing fuzz-testing/testcases fuzz-testing/out - $(MAKE) temp_fuzzer -C test CXX=afl-clang++ - mv test/temp_fuzzer fuzz-testing/fuzzer - find test/data -size -5k -name *.bson | xargs -I{} cp "{}" fuzz-testing/testcases - @echo "Execute: afl-fuzz -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer" - fuzzing-start: afl-fuzz -S fuzzer1 -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer > /dev/null & afl-fuzz -S fuzzer2 -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer > /dev/null & diff --git a/test/Makefile b/test/Makefile index 9b8150b51b..eeb16c3519 100644 --- a/test/Makefile +++ b/test/Makefile @@ -94,7 +94,7 @@ check: $(OBJECTS) $(TESTCASES) ############################################################################## FUZZER_ENGINE = src/fuzzer-driver_afl.cpp -FUZZERS = parse_afl_fuzzer parse_bson_fuzzer parse_cbor_fuzzer parse_msgpack_fuzzer parse_ubjson_fuzzer temp_fuzzer +FUZZERS = parse_afl_fuzzer parse_bson_fuzzer parse_cbor_fuzzer parse_msgpack_fuzzer parse_ubjson_fuzzer fuzzers: $(FUZZERS) parse_afl_fuzzer: @@ -112,5 +112,3 @@ parse_msgpack_fuzzer: parse_ubjson_fuzzer: $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(FUZZER_ENGINE) src/fuzzer-parse_ubjson.cpp -o $@ -temp_fuzzer: - $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(FUZZER_ENGINE) src/fuzzer-temp.cpp -o $@ diff --git a/test/src/fuzzer-temp.cpp b/test/src/fuzzer-temp.cpp deleted file mode 100644 index b1b25d84d8..0000000000 --- a/test/src/fuzzer-temp.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/* - __ _____ _____ _____ - __| | __| | | | JSON for Modern C++ (fuzz test support) -| | |__ | | | | | | version 3.7.3 -|_____|_____|_____|_|___| https://github.com/nlohmann/json - -This file implements a parser test suitable for fuzz testing. Given a byte -array data, it performs the following steps: - -- j1 = from_bson(data) -- vec = to_bson(j1) -- j2 = from_bson(vec) -- assert(j1 == j2) - -The provided function `LLVMFuzzerTestOneInput` can be used in different fuzzer -drivers. - -Licensed under the MIT License . -*/ - -#include -#include -#include - -using json = nlohmann::json; - -// see http://llvm.org/docs/LibFuzzer.html -extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) -{ - try - { - // step 1: parse input - std::vector vec1(data, data + size); - json j1 = json::from_bson(vec1); - - if (j1.is_discarded()) - { - return 0; - } - - try - { - // step 2: round trip - std::vector vec2 = json::to_bson(j1); - - // parse serialization - json j2 = json::from_bson(vec2); - - // serializations must match - assert(json::to_bson(j2) == vec2); - } - catch (const json::parse_error&) - { - // parsing a BSON serialization must not fail - assert(false); - } - } - catch (const json::parse_error&) - { - // parse errors are ok, because input may be random bytes - } - catch (const json::type_error&) - { - // type errors can occur during parsing, too - } - catch (const json::out_of_range&) - { - // out of range errors can occur during parsing, too - } - - // return 0 - non-zero return values are reserved for future use - return 0; -} From 35ce214901b448b6e6b70c679162ccec796565d5 Mon Sep 17 00:00:00 2001 From: Tanuj Garg Date: Sat, 30 May 2020 01:26:16 +0530 Subject: [PATCH 07/26] fuzzer, testing conversion from vector & deque to json, added --- Makefile | 9 ++++ test/Makefile | 4 +- test/src/fuzzer-parse_stl.cpp | 78 +++++++++++++++++++++++++++++++++++ 3 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 test/src/fuzzer-parse_stl.cpp diff --git a/Makefile b/Makefile index 08c40d2f34..558c4da3ee 100644 --- a/Makefile +++ b/Makefile @@ -44,6 +44,7 @@ all: @echo "fuzz_testing_cbor - prepare fuzz testing of the CBOR parser" @echo "fuzz_testing_msgpack - prepare fuzz testing of the MessagePack parser" @echo "fuzz_testing_ubjson - prepare fuzz testing of the UBJSON parser" + @echo "fuzz_testing_stl - prepare fuzz testing of the STL parser" @echo "json_unit - create single-file test executable" @echo "pedantic_clang - run Clang with maximal warning flags" @echo "pedantic_gcc - run GCC with maximal warning flags" @@ -402,6 +403,14 @@ fuzz_testing_ubjson: find test/data -size -5k -name *.ubjson | xargs -I{} cp "{}" fuzz-testing/testcases @echo "Execute: afl-fuzz -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer" +fuzz_testing_msgpack: + rm -fr fuzz-testing + mkdir -p fuzz-testing fuzz-testing/testcases fuzz-testing/out + $(MAKE) parse_stl_fuzzer -C test CXX=afl-clang++ + mv test/parse_stl_fuzzer fuzz-testing/fuzzer + find test/data -size -5k -name *.json | xargs -I{} cp "{}" fuzz-testing/testcases + @echo "Execute: afl-fuzz -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer" + fuzzing-start: afl-fuzz -S fuzzer1 -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer > /dev/null & afl-fuzz -S fuzzer2 -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer > /dev/null & diff --git a/test/Makefile b/test/Makefile index eeb16c3519..5281dacb7b 100644 --- a/test/Makefile +++ b/test/Makefile @@ -94,7 +94,7 @@ check: $(OBJECTS) $(TESTCASES) ############################################################################## FUZZER_ENGINE = src/fuzzer-driver_afl.cpp -FUZZERS = parse_afl_fuzzer parse_bson_fuzzer parse_cbor_fuzzer parse_msgpack_fuzzer parse_ubjson_fuzzer +FUZZERS = parse_afl_fuzzer parse_bson_fuzzer parse_cbor_fuzzer parse_msgpack_fuzzer parse_ubjson_fuzzer parse_stl_fuzzer fuzzers: $(FUZZERS) parse_afl_fuzzer: @@ -112,3 +112,5 @@ parse_msgpack_fuzzer: parse_ubjson_fuzzer: $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(FUZZER_ENGINE) src/fuzzer-parse_ubjson.cpp -o $@ +parse_stl_fuzzer: + $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(FUZZER_ENGINE) src/fuzzer-parse_stl.cpp -o $@ diff --git a/test/src/fuzzer-parse_stl.cpp b/test/src/fuzzer-parse_stl.cpp new file mode 100644 index 0000000000..b33dc42ed9 --- /dev/null +++ b/test/src/fuzzer-parse_stl.cpp @@ -0,0 +1,78 @@ +/* + __ _____ _____ _____ + __| | __| | | | JSON for Modern C++ (fuzz test support) +| | |__ | | | | | | version 3.7.3 +|_____|_____|_____|_|___| https://github.com/nlohmann/json + +This file implements a parser test suitable for fuzz testing. Given a byte +array data, it performs the following steps: + +- j1 = parse(data) +- s1 = serialize(j1) +- j2 = parse(s1) +- s2 = serialize(j2) +- assert(s1 == s2) + +The provided function `LLVMFuzzerTestOneInput` can be used in different fuzzer +drivers. + +Licensed under the MIT License . +*/ + +#include +#include +#include +#include + +using json = nlohmann::json; + +// see http://llvm.org/docs/LibFuzzer.html +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) +{ + std::vector vec1(data, data+size); + std::deque deque1(data, data+size); + + json j_vector(vec1); + json j_deque(deque1); + + assert(j_vector == j_deque); + + // try + // { + // // step 1: parse input + // json j1 = json::parse(data, data + size); + + // try + // { + // // step 2: round trip + + // // first serialization + // std::string s1 = j1.dump(); + + // // parse serialization + // json j2 = json::parse(s1); + + // // second serialization + // std::string s2 = j2.dump(); + + // // serializations must match + // assert(s1 == s2); + // } + // catch (const json::parse_error&) + // { + // // parsing a JSON serialization must not fail + // assert(false); + // } + // } + // catch (const json::parse_error&) + // { + // // parse errors are ok, because input may be random bytes + // } + // catch (const json::out_of_range&) + // { + // // out of range errors may happen if provided sizes are excessive + // } + + // return 0 - non-zero return values are reserved for future use + return 0; +} From 5d501bf7e3618d1f4db3393a7d86c63d6af76a28 Mon Sep 17 00:00:00 2001 From: Tanuj Garg Date: Sat, 30 May 2020 19:32:19 +0530 Subject: [PATCH 08/26] added conversion from other stl sequence containers to json added --- test/src/fuzzer-parse_stl.cpp | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/test/src/fuzzer-parse_stl.cpp b/test/src/fuzzer-parse_stl.cpp index b33dc42ed9..6561d5aac6 100644 --- a/test/src/fuzzer-parse_stl.cpp +++ b/test/src/fuzzer-parse_stl.cpp @@ -20,7 +20,10 @@ Licensed under the MIT License . */ #include -#include +#include +#include +#include +#include #include #include @@ -29,13 +32,27 @@ using json = nlohmann::json; // see http://llvm.org/docs/LibFuzzer.html extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - std::vector vec1(data, data+size); - std::deque deque1(data, data+size); - - json j_vector(vec1); - json j_deque(deque1); + std::vector vec(data, data+size); + std::deque deq(data, data+size); + std::list lst(data, data+size); + std::forward_list flist(data, data+size); + std::set st(data, data+size); + std::unordered_set ust(data, data+size); + std::multiset mst(data, data+size); + std::unordered_multiset umst(data, data+size); + + json j_vector(vec); + json j_deque(deq); + json j_list(lst); + json j_flist(flist); + json j_set(st); + json j_uset(ust); + json j_mset(mst); + json j_umset(umst); assert(j_vector == j_deque); + assert(j_vector == j_list); + assert(j_vector == j_flist); // try // { From 74a04708cffaf628841acfb0be1a1be8ed7fe359 Mon Sep 17 00:00:00 2001 From: Tanuj Garg Date: Mon, 1 Jun 2020 09:14:53 +0530 Subject: [PATCH 09/26] Added conversion from various maps to json --- test/src/fuzzer-parse_stl.cpp | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/test/src/fuzzer-parse_stl.cpp b/test/src/fuzzer-parse_stl.cpp index 6561d5aac6..8f4c17d944 100644 --- a/test/src/fuzzer-parse_stl.cpp +++ b/test/src/fuzzer-parse_stl.cpp @@ -24,6 +24,10 @@ Licensed under the MIT License . #include #include #include +#include +#include +#include +#include #include #include @@ -32,6 +36,7 @@ using json = nlohmann::json; // see http://llvm.org/docs/LibFuzzer.html extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + // putting data in several STL containers std::vector vec(data, data+size); std::deque deq(data, data+size); std::list lst(data, data+size); @@ -41,19 +46,41 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) std::multiset mst(data, data+size); std::unordered_multiset umst(data, data+size); + // parsing from STL containers json j_vector(vec); json j_deque(deq); json j_list(lst); json j_flist(flist); json j_set(st); json j_uset(ust); - json j_mset(mst); - json j_umset(umst); + json j_multiset(mst); + json j_umultiset(umst); + // json must be same for sequence containers assert(j_vector == j_deque); assert(j_vector == j_list); assert(j_vector == j_flist); + map mp; + unordered_map ump; + multimap mmp; + unordered_multimap ummp; + + // converting each consecutive entry in the vector into a key-value pair + for(int i=1; i insert_data = make_pair(vec[i-1], vec[i]); + mp.insert(insert_data); + ump.insert(insert_data); + mmp.insert(insert_data); + ummp.insert(insert_data); + } + + json j_map(mp); + json j_umap(ump); + json j_multimap(mmp); + json j_umultimap(ummp); + // try // { // // step 1: parse input From c66806b8bc368b2d52e23b27886d3a195036c795 Mon Sep 17 00:00:00 2001 From: Tanuj Garg Date: Mon, 1 Jun 2020 09:29:04 +0530 Subject: [PATCH 10/26] removed namespace bug --- test/src/fuzzer-parse_stl.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/src/fuzzer-parse_stl.cpp b/test/src/fuzzer-parse_stl.cpp index 8f4c17d944..282681f0b9 100644 --- a/test/src/fuzzer-parse_stl.cpp +++ b/test/src/fuzzer-parse_stl.cpp @@ -61,15 +61,15 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) assert(j_vector == j_list); assert(j_vector == j_flist); - map mp; - unordered_map ump; - multimap mmp; - unordered_multimap ummp; + std::map mp; + std::unordered_map ump; + std::multimap mmp; + std::unordered_multimap ummp; // converting each consecutive entry in the vector into a key-value pair for(int i=1; i insert_data = make_pair(vec[i-1], vec[i]); + std::pair insert_data = std::make_pair(vec[i-1], vec[i]); mp.insert(insert_data); ump.insert(insert_data); mmp.insert(insert_data); From 57c88514392781fb7a724d979e92746a98336498 Mon Sep 17 00:00:00 2001 From: Tanuj Garg Date: Mon, 1 Jun 2020 09:55:01 +0530 Subject: [PATCH 11/26] added parsing from vector and deque --- test/src/fuzzer-parse_stl.cpp | 39 +++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/test/src/fuzzer-parse_stl.cpp b/test/src/fuzzer-parse_stl.cpp index 282681f0b9..50f9236b73 100644 --- a/test/src/fuzzer-parse_stl.cpp +++ b/test/src/fuzzer-parse_stl.cpp @@ -37,14 +37,14 @@ using json = nlohmann::json; extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { // putting data in several STL containers - std::vector vec(data, data+size); - std::deque deq(data, data+size); - std::list lst(data, data+size); - std::forward_list flist(data, data+size); - std::set st(data, data+size); - std::unordered_set ust(data, data+size); - std::multiset mst(data, data+size); - std::unordered_multiset umst(data, data+size); + std::vector vec(data, data + size); + std::deque deq(data, data + size); + std::list lst(data, data + size); + std::forward_list flist(data, data + size); + std::set st(data, data + size); + std::unordered_set ust(data, data + size); + std::multiset mst(data, data + size); + std::unordered_multiset umst(data, data + size); // parsing from STL containers json j_vector(vec); @@ -67,7 +67,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) std::unordered_multimap ummp; // converting each consecutive entry in the vector into a key-value pair - for(int i=1; i insert_data = std::make_pair(vec[i-1], vec[i]); mp.insert(insert_data); @@ -81,6 +81,27 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) json j_multimap(mmp); json j_umultimap(ummp); + try + { + // parse input directly + json j1 = json::parse(data, data + size); + // parse using vector + json j_vec = json::parse(vec); + // parse using deque + json j_deq = json::parse(deq); + + // all three must be equal + assert(j1 == j_vec); + assert(j1 == j_deq); + } + catch (const json::parse_error&) + { + // parse errors are ok, because input may be random bytes + } + catch (const json::out_of_range&) + { + // out of range errors may happen if provided sizes are excessive + } // try // { // // step 1: parse input From 5868e7f2898c995de46498595242cfc1d455daed Mon Sep 17 00:00:00 2001 From: Tanuj Garg Date: Mon, 1 Jun 2020 12:32:11 +0530 Subject: [PATCH 12/26] added looping in vector & map, and tested get(), push_back() & emplace_back() methods --- test/src/fuzzer-parse_stl.cpp | 80 ++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 38 deletions(-) diff --git a/test/src/fuzzer-parse_stl.cpp b/test/src/fuzzer-parse_stl.cpp index 50f9236b73..19082e06d7 100644 --- a/test/src/fuzzer-parse_stl.cpp +++ b/test/src/fuzzer-parse_stl.cpp @@ -61,13 +61,47 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) assert(j_vector == j_list); assert(j_vector == j_flist); + // iterating json array and testing get() method + for(json::iterator it = j_vector.begin(); it != j_vector.end(); ++it) + { + try + { + int temp = (*it).get(); + } + catch(const json::type_error) + { + // input might not be convertible to integer + } + } + + for(auto& element : j_vector) + { + // range-based iteration + } + + json j_vector2; + json j_vector3; + + for(int i = 0; i < (int)j_vector.size(); ++i) + { + auto temp = j_vector.at(i); + // testing at() method + j_vector2.push_back(temp); + j_vector3.emplace_back(temp); + // testing push_back and emplace back methods + } + + // these jsons must be the same + assert(j_vector == j_vector2); + assert(j_vector == j_vector3); + std::map mp; std::unordered_map ump; std::multimap mmp; std::unordered_multimap ummp; // converting each consecutive entry in the vector into a key-value pair - for(int i=1; i insert_data = std::make_pair(vec[i-1], vec[i]); mp.insert(insert_data); @@ -81,6 +115,13 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) json j_multimap(mmp); json j_umultimap(ummp); + // iterating json map + for(json::iterator it = j_map.begin(); it != j_map.end(); ++it) + { + auto temp1 = it.key(); + auto temp2 = it.value(); + } + try { // parse input directly @@ -102,42 +143,5 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { // out of range errors may happen if provided sizes are excessive } - // try - // { - // // step 1: parse input - // json j1 = json::parse(data, data + size); - - // try - // { - // // step 2: round trip - - // // first serialization - // std::string s1 = j1.dump(); - - // // parse serialization - // json j2 = json::parse(s1); - - // // second serialization - // std::string s2 = j2.dump(); - - // // serializations must match - // assert(s1 == s2); - // } - // catch (const json::parse_error&) - // { - // // parsing a JSON serialization must not fail - // assert(false); - // } - // } - // catch (const json::parse_error&) - // { - // // parse errors are ok, because input may be random bytes - // } - // catch (const json::out_of_range&) - // { - // // out of range errors may happen if provided sizes are excessive - // } - - // return 0 - non-zero return values are reserved for future use return 0; } From 9388bb2627bf554ad490abd554a4251f55c7bd37 Mon Sep 17 00:00:00 2001 From: Tanuj Garg Date: Mon, 1 Jun 2020 13:56:11 +0530 Subject: [PATCH 13/26] changed datatype of key in maps from uint8_t to std::string --- test/src/fuzzer-parse_stl.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/src/fuzzer-parse_stl.cpp b/test/src/fuzzer-parse_stl.cpp index 19082e06d7..ac2dbf2c8c 100644 --- a/test/src/fuzzer-parse_stl.cpp +++ b/test/src/fuzzer-parse_stl.cpp @@ -95,15 +95,15 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) assert(j_vector == j_vector2); assert(j_vector == j_vector3); - std::map mp; - std::unordered_map ump; - std::multimap mmp; - std::unordered_multimap ummp; + std::map mp; + std::unordered_map ump; + std::multimap mmp; + std::unordered_multimap ummp; // converting each consecutive entry in the vector into a key-value pair for(int i = 1; i < (int)vec.size(); i+=2) { - std::pair insert_data = std::make_pair(vec[i-1], vec[i]); + std::pair insert_data = std::make_pair(std::to_string(vec[i-1]), vec[i]); mp.insert(insert_data); ump.insert(insert_data); mmp.insert(insert_data); From 5c51ebb8749025b3c8051651cd4191f2ebea688f Mon Sep 17 00:00:00 2001 From: Tanuj Garg Date: Mon, 1 Jun 2020 14:28:57 +0530 Subject: [PATCH 14/26] initialized json with empty array to test push_back & emplace_back methods --- test/src/fuzzer-parse_stl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/src/fuzzer-parse_stl.cpp b/test/src/fuzzer-parse_stl.cpp index ac2dbf2c8c..6b4a489758 100644 --- a/test/src/fuzzer-parse_stl.cpp +++ b/test/src/fuzzer-parse_stl.cpp @@ -79,8 +79,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) // range-based iteration } - json j_vector2; - json j_vector3; + json j_vector2 = json::array(); + json j_vector3 = json::array(); for(int i = 0; i < (int)j_vector.size(); ++i) { From 35ac9319c84d554dcff17767e0f99f9f96b39a5b Mon Sep 17 00:00:00 2001 From: Tanuj Garg Date: Wed, 3 Jun 2020 00:20:47 +0530 Subject: [PATCH 15/26] resolved all warnings --- test/src/fuzzer-parse_stl.cpp | 43 +++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/test/src/fuzzer-parse_stl.cpp b/test/src/fuzzer-parse_stl.cpp index 6b4a489758..5253c8a397 100644 --- a/test/src/fuzzer-parse_stl.cpp +++ b/test/src/fuzzer-parse_stl.cpp @@ -42,9 +42,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) std::list lst(data, data + size); std::forward_list flist(data, data + size); std::set st(data, data + size); - std::unordered_set ust(data, data + size); - std::multiset mst(data, data + size); - std::unordered_multiset umst(data, data + size); + std::unordered_set uset(data, data + size); + std::multiset multist(data, data + size); + std::unordered_multiset umultiset(data, data + size); // parsing from STL containers json j_vector(vec); @@ -52,9 +52,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) json j_list(lst); json j_flist(flist); json j_set(st); - json j_uset(ust); - json j_multiset(mst); - json j_umultiset(umst); + json j_uset(uset); + json j_multiset(multist); + json j_umultiset(umultiset); // json must be same for sequence containers assert(j_vector == j_deque); @@ -82,7 +82,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) json j_vector2 = json::array(); json j_vector3 = json::array(); - for(int i = 0; i < (int)j_vector.size(); ++i) + for(std::size_t i = 0; i < j_vector.size(); ++i) { auto temp = j_vector.at(i); // testing at() method @@ -91,29 +91,32 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) // testing push_back and emplace back methods } - // these jsons must be the same + // these three json vectors must be the same assert(j_vector == j_vector2); assert(j_vector == j_vector3); std::map mp; - std::unordered_map ump; - std::multimap mmp; - std::unordered_multimap ummp; + std::unordered_map umap; + std::multimap multimp; + std::unordered_multimap umultimap; - // converting each consecutive entry in the vector into a key-value pair - for(int i = 1; i < (int)vec.size(); i+=2) + // converting each consecutive entry in the vector into a key-value pair and adding them to map + for(std::size_t i = 1; i < vec.size(); i+=2) { - std::pair insert_data = std::make_pair(std::to_string(vec[i-1]), vec[i]); + int last_entry = static_cast(vec[i-1]); + std::string key_str = std::to_string(last_entry); + std::pair insert_data = std::make_pair(key_str, vec[i]); mp.insert(insert_data); - ump.insert(insert_data); - mmp.insert(insert_data); - ummp.insert(insert_data); + umap.insert(insert_data); + multimp.insert(insert_data); + umultimap.insert(insert_data); } + // map -> json map json j_map(mp); - json j_umap(ump); - json j_multimap(mmp); - json j_umultimap(ummp); + json j_umap(umap); + json j_multimap(multimp); + json j_umultimap(umultimap); // iterating json map for(json::iterator it = j_map.begin(); it != j_map.end(); ++it) From 2efdbfa3153696cf3294aa4b8ebcd927fb3ab295 Mon Sep 17 00:00:00 2001 From: Tanuj Garg Date: Wed, 3 Jun 2020 13:46:28 +0530 Subject: [PATCH 16/26] removed deque parsing because deque is not a contiguous byte sequence when it has large data --- test/src/fuzzer-parse_stl.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/test/src/fuzzer-parse_stl.cpp b/test/src/fuzzer-parse_stl.cpp index 5253c8a397..0eb6fcdd61 100644 --- a/test/src/fuzzer-parse_stl.cpp +++ b/test/src/fuzzer-parse_stl.cpp @@ -131,12 +131,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) json j1 = json::parse(data, data + size); // parse using vector json j_vec = json::parse(vec); - // parse using deque - json j_deq = json::parse(deq); - // all three must be equal + // both of them must be equal assert(j1 == j_vec); - assert(j1 == j_deq); } catch (const json::parse_error&) { From 6e81c785454000a7f6a27700188dee0a06f28e04 Mon Sep 17 00:00:00 2001 From: Tanuj Garg Date: Fri, 5 Jun 2020 22:14:32 +0530 Subject: [PATCH 17/26] [Checking stats] Keeping only conversion from stl containers --- test/src/fuzzer-parse_stl.cpp | 83 ----------------------------------- 1 file changed, 83 deletions(-) diff --git a/test/src/fuzzer-parse_stl.cpp b/test/src/fuzzer-parse_stl.cpp index 0eb6fcdd61..38a417c4c3 100644 --- a/test/src/fuzzer-parse_stl.cpp +++ b/test/src/fuzzer-parse_stl.cpp @@ -60,88 +60,5 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) assert(j_vector == j_deque); assert(j_vector == j_list); assert(j_vector == j_flist); - - // iterating json array and testing get() method - for(json::iterator it = j_vector.begin(); it != j_vector.end(); ++it) - { - try - { - int temp = (*it).get(); - } - catch(const json::type_error) - { - // input might not be convertible to integer - } - } - - for(auto& element : j_vector) - { - // range-based iteration - } - - json j_vector2 = json::array(); - json j_vector3 = json::array(); - - for(std::size_t i = 0; i < j_vector.size(); ++i) - { - auto temp = j_vector.at(i); - // testing at() method - j_vector2.push_back(temp); - j_vector3.emplace_back(temp); - // testing push_back and emplace back methods - } - - // these three json vectors must be the same - assert(j_vector == j_vector2); - assert(j_vector == j_vector3); - - std::map mp; - std::unordered_map umap; - std::multimap multimp; - std::unordered_multimap umultimap; - - // converting each consecutive entry in the vector into a key-value pair and adding them to map - for(std::size_t i = 1; i < vec.size(); i+=2) - { - int last_entry = static_cast(vec[i-1]); - std::string key_str = std::to_string(last_entry); - std::pair insert_data = std::make_pair(key_str, vec[i]); - mp.insert(insert_data); - umap.insert(insert_data); - multimp.insert(insert_data); - umultimap.insert(insert_data); - } - - // map -> json map - json j_map(mp); - json j_umap(umap); - json j_multimap(multimp); - json j_umultimap(umultimap); - - // iterating json map - for(json::iterator it = j_map.begin(); it != j_map.end(); ++it) - { - auto temp1 = it.key(); - auto temp2 = it.value(); - } - - try - { - // parse input directly - json j1 = json::parse(data, data + size); - // parse using vector - json j_vec = json::parse(vec); - - // both of them must be equal - assert(j1 == j_vec); - } - catch (const json::parse_error&) - { - // parse errors are ok, because input may be random bytes - } - catch (const json::out_of_range&) - { - // out of range errors may happen if provided sizes are excessive - } return 0; } From c06ee977f41b9f81cb89a4362447c01082a33d46 Mon Sep 17 00:00:00 2001 From: Tanuj Garg Date: Fri, 5 Jun 2020 22:50:40 +0530 Subject: [PATCH 18/26] [Checking stats] Keeping only iterating a json vector container --- test/src/fuzzer-parse_stl.cpp | 36 +++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/test/src/fuzzer-parse_stl.cpp b/test/src/fuzzer-parse_stl.cpp index 38a417c4c3..13d709a3d4 100644 --- a/test/src/fuzzer-parse_stl.cpp +++ b/test/src/fuzzer-parse_stl.cpp @@ -38,27 +38,27 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { // putting data in several STL containers std::vector vec(data, data + size); - std::deque deq(data, data + size); - std::list lst(data, data + size); - std::forward_list flist(data, data + size); - std::set st(data, data + size); - std::unordered_set uset(data, data + size); - std::multiset multist(data, data + size); - std::unordered_multiset umultiset(data, data + size); // parsing from STL containers json j_vector(vec); - json j_deque(deq); - json j_list(lst); - json j_flist(flist); - json j_set(st); - json j_uset(uset); - json j_multiset(multist); - json j_umultiset(umultiset); - // json must be same for sequence containers - assert(j_vector == j_deque); - assert(j_vector == j_list); - assert(j_vector == j_flist); + // iterating json array and testing get() method + for(json::iterator it = j_vector.begin(); it != j_vector.end(); ++it) + { + try + { + int temp = (*it).get(); + } + catch(const json::type_error) + { + // input might not be convertible to integer + } + } + + for(auto& element : j_vector) + { + // range-based iteration + } + return 0; } From 02c901ef1182ddabdfb041f60d75e876baa6755e Mon Sep 17 00:00:00 2001 From: Tanuj Garg Date: Fri, 5 Jun 2020 23:33:49 +0530 Subject: [PATCH 19/26] [Checking stats] Keeping only stl like operations on json vector --- test/src/fuzzer-parse_stl.cpp | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/test/src/fuzzer-parse_stl.cpp b/test/src/fuzzer-parse_stl.cpp index 13d709a3d4..c338057c32 100644 --- a/test/src/fuzzer-parse_stl.cpp +++ b/test/src/fuzzer-parse_stl.cpp @@ -36,29 +36,21 @@ using json = nlohmann::json; // see http://llvm.org/docs/LibFuzzer.html extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - // putting data in several STL containers - std::vector vec(data, data + size); + json j_vector2 = json::array(); + json j_vector3 = json::array(); - // parsing from STL containers - json j_vector(vec); - - // iterating json array and testing get() method - for(json::iterator it = j_vector.begin(); it != j_vector.end(); ++it) + for(std::size_t i = 0; i < j_vector.size(); ++i) { - try - { - int temp = (*it).get(); - } - catch(const json::type_error) - { - // input might not be convertible to integer - } + auto temp = j_vector.at(i); + // testing at() method + j_vector2.push_back(temp); + j_vector3.emplace_back(temp); + // testing push_back and emplace back methods } - for(auto& element : j_vector) - { - // range-based iteration - } + // these three json vectors must be the same + assert(j_vector == j_vector2); + assert(j_vector == j_vector3); return 0; } From 2cd43525ea0164cac9b3d7376488c804bb22967c Mon Sep 17 00:00:00 2001 From: Tanuj Garg Date: Fri, 5 Jun 2020 23:38:18 +0530 Subject: [PATCH 20/26] [Checking stats] resolved compile error --- test/src/fuzzer-parse_stl.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/src/fuzzer-parse_stl.cpp b/test/src/fuzzer-parse_stl.cpp index c338057c32..3620db453f 100644 --- a/test/src/fuzzer-parse_stl.cpp +++ b/test/src/fuzzer-parse_stl.cpp @@ -36,6 +36,12 @@ using json = nlohmann::json; // see http://llvm.org/docs/LibFuzzer.html extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + // putting data in several STL containers + std::vector vec(data, data + size); + + // parsing from STL containers + json j_vector(vec); + json j_vector2 = json::array(); json j_vector3 = json::array(); From f3c70224871b86bd90810c3978bb55338d9fc548 Mon Sep 17 00:00:00 2001 From: Tanuj Garg Date: Fri, 5 Jun 2020 23:55:50 +0530 Subject: [PATCH 21/26] [Checking stats] Keeping only map coversions to json --- test/src/fuzzer-parse_stl.cpp | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/test/src/fuzzer-parse_stl.cpp b/test/src/fuzzer-parse_stl.cpp index 3620db453f..78fd617ac3 100644 --- a/test/src/fuzzer-parse_stl.cpp +++ b/test/src/fuzzer-parse_stl.cpp @@ -42,21 +42,28 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) // parsing from STL containers json j_vector(vec); - json j_vector2 = json::array(); - json j_vector3 = json::array(); + std::map mp; + std::unordered_map umap; + std::multimap multimp; + std::unordered_multimap umultimap; - for(std::size_t i = 0; i < j_vector.size(); ++i) + // converting each consecutive entry in the vector into a key-value pair and adding them to map + for(std::size_t i = 1; i < vec.size(); i+=2) { - auto temp = j_vector.at(i); - // testing at() method - j_vector2.push_back(temp); - j_vector3.emplace_back(temp); - // testing push_back and emplace back methods + int last_entry = static_cast(vec[i-1]); + std::string key_str = std::to_string(last_entry); + std::pair insert_data = std::make_pair(key_str, vec[i]); + mp.insert(insert_data); + umap.insert(insert_data); + multimp.insert(insert_data); + umultimap.insert(insert_data); } - // these three json vectors must be the same - assert(j_vector == j_vector2); - assert(j_vector == j_vector3); + // map -> json map + json j_map(mp); + json j_umap(umap); + json j_multimap(multimp); + json j_umultimap(umultimap); return 0; } From f1f38cf908a94ef412afb65c9b9d3a6f13bc6ddf Mon Sep 17 00:00:00 2001 From: Tanuj Garg Date: Sat, 6 Jun 2020 00:45:03 +0530 Subject: [PATCH 22/26] [Checking stats] keeping only stl like operations --- test/src/fuzzer-parse_stl.cpp | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/test/src/fuzzer-parse_stl.cpp b/test/src/fuzzer-parse_stl.cpp index 78fd617ac3..3620db453f 100644 --- a/test/src/fuzzer-parse_stl.cpp +++ b/test/src/fuzzer-parse_stl.cpp @@ -42,28 +42,21 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) // parsing from STL containers json j_vector(vec); - std::map mp; - std::unordered_map umap; - std::multimap multimp; - std::unordered_multimap umultimap; + json j_vector2 = json::array(); + json j_vector3 = json::array(); - // converting each consecutive entry in the vector into a key-value pair and adding them to map - for(std::size_t i = 1; i < vec.size(); i+=2) + for(std::size_t i = 0; i < j_vector.size(); ++i) { - int last_entry = static_cast(vec[i-1]); - std::string key_str = std::to_string(last_entry); - std::pair insert_data = std::make_pair(key_str, vec[i]); - mp.insert(insert_data); - umap.insert(insert_data); - multimp.insert(insert_data); - umultimap.insert(insert_data); + auto temp = j_vector.at(i); + // testing at() method + j_vector2.push_back(temp); + j_vector3.emplace_back(temp); + // testing push_back and emplace back methods } - // map -> json map - json j_map(mp); - json j_umap(umap); - json j_multimap(multimp); - json j_umultimap(umultimap); + // these three json vectors must be the same + assert(j_vector == j_vector2); + assert(j_vector == j_vector3); return 0; } From a94e1af71cad8a63d898c69ff187f1527e904ac0 Mon Sep 17 00:00:00 2001 From: Tanuj Garg Date: Sat, 6 Jun 2020 01:04:43 +0530 Subject: [PATCH 23/26] [Checking stats] Keeping json map iteration --- test/src/fuzzer-parse_stl.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/test/src/fuzzer-parse_stl.cpp b/test/src/fuzzer-parse_stl.cpp index 3620db453f..3e6d82a2bc 100644 --- a/test/src/fuzzer-parse_stl.cpp +++ b/test/src/fuzzer-parse_stl.cpp @@ -42,21 +42,21 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) // parsing from STL containers json j_vector(vec); - json j_vector2 = json::array(); - json j_vector3 = json::array(); - - for(std::size_t i = 0; i < j_vector.size(); ++i) + std::map mp; + for(std::size_t i = 1; i < vec.size(); i+=2) { - auto temp = j_vector.at(i); - // testing at() method - j_vector2.push_back(temp); - j_vector3.emplace_back(temp); - // testing push_back and emplace back methods + int last_entry = static_cast(vec[i-1]); + std::string key_str = std::to_string(last_entry); + std::pair insert_data = std::make_pair(key_str, vec[i]); + mp.insert(insert_data); + } + json j_map(mp); + // iterating json map + for(json::iterator it = j_map.begin(); it != j_map.end(); ++it) + { + auto temp1 = it.key(); + auto temp2 = it.value(); } - - // these three json vectors must be the same - assert(j_vector == j_vector2); - assert(j_vector == j_vector3); return 0; } From 88194fd52072d20af5ca4b46273ccd8098e63353 Mon Sep 17 00:00:00 2001 From: Tanuj Garg Date: Sat, 6 Jun 2020 01:21:27 +0530 Subject: [PATCH 24/26] [Checking stats] Keeping only parsing vector --- test/src/fuzzer-parse_stl.cpp | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/test/src/fuzzer-parse_stl.cpp b/test/src/fuzzer-parse_stl.cpp index 3e6d82a2bc..9a6a440321 100644 --- a/test/src/fuzzer-parse_stl.cpp +++ b/test/src/fuzzer-parse_stl.cpp @@ -36,27 +36,23 @@ using json = nlohmann::json; // see http://llvm.org/docs/LibFuzzer.html extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - // putting data in several STL containers - std::vector vec(data, data + size); - - // parsing from STL containers - json j_vector(vec); + try + { + // parse input directly + json j1 = json::parse(data, data + size); + // parse using vector + json j_vec = json::parse(vec); - std::map mp; - for(std::size_t i = 1; i < vec.size(); i+=2) + // both of them must be equal + assert(j1 == j_vec); + } + catch (const json::parse_error&) { - int last_entry = static_cast(vec[i-1]); - std::string key_str = std::to_string(last_entry); - std::pair insert_data = std::make_pair(key_str, vec[i]); - mp.insert(insert_data); + // parse errors are ok, because input may be random bytes } - json j_map(mp); - // iterating json map - for(json::iterator it = j_map.begin(); it != j_map.end(); ++it) + catch (const json::out_of_range&) { - auto temp1 = it.key(); - auto temp2 = it.value(); + // out of range errors may happen if provided sizes are excessive } - return 0; } From d402b6a167c5114c06ded3b2afc8c0d14d177e48 Mon Sep 17 00:00:00 2001 From: Tanuj Garg Date: Sat, 6 Jun 2020 01:28:56 +0530 Subject: [PATCH 25/26] [Checking stats] resolved compiler error --- test/src/fuzzer-parse_stl.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/src/fuzzer-parse_stl.cpp b/test/src/fuzzer-parse_stl.cpp index 9a6a440321..6fe87f48cf 100644 --- a/test/src/fuzzer-parse_stl.cpp +++ b/test/src/fuzzer-parse_stl.cpp @@ -36,6 +36,12 @@ using json = nlohmann::json; // see http://llvm.org/docs/LibFuzzer.html extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + // putting data in several STL containers + std::vector vec(data, data + size); + + // parsing from STL containers + json j_vector(vec); + try { // parse input directly @@ -54,5 +60,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { // out of range errors may happen if provided sizes are excessive } + return 0; } From 0afebec7741f166d37c111b047cfdda383aa4ace Mon Sep 17 00:00:00 2001 From: Tanuj Garg Date: Sat, 6 Jun 2020 19:55:37 +0530 Subject: [PATCH 26/26] Added complete data and renamed files and fuzzer --- Makefile | 8 +- test/Makefile | 6 +- test/src/fuzzer-parse_stl.cpp | 65 -------------- test/src/fuzzer-stl_operations.cpp | 140 +++++++++++++++++++++++++++++ 4 files changed, 147 insertions(+), 72 deletions(-) delete mode 100644 test/src/fuzzer-parse_stl.cpp create mode 100644 test/src/fuzzer-stl_operations.cpp diff --git a/Makefile b/Makefile index 558c4da3ee..b45f8afb83 100644 --- a/Makefile +++ b/Makefile @@ -44,7 +44,7 @@ all: @echo "fuzz_testing_cbor - prepare fuzz testing of the CBOR parser" @echo "fuzz_testing_msgpack - prepare fuzz testing of the MessagePack parser" @echo "fuzz_testing_ubjson - prepare fuzz testing of the UBJSON parser" - @echo "fuzz_testing_stl - prepare fuzz testing of the STL parser" + @echo "fuzz_testing_stl - prepare fuzz testing of STL operators" @echo "json_unit - create single-file test executable" @echo "pedantic_clang - run Clang with maximal warning flags" @echo "pedantic_gcc - run GCC with maximal warning flags" @@ -403,11 +403,11 @@ fuzz_testing_ubjson: find test/data -size -5k -name *.ubjson | xargs -I{} cp "{}" fuzz-testing/testcases @echo "Execute: afl-fuzz -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer" -fuzz_testing_msgpack: +fuzz_testing_stl: rm -fr fuzz-testing mkdir -p fuzz-testing fuzz-testing/testcases fuzz-testing/out - $(MAKE) parse_stl_fuzzer -C test CXX=afl-clang++ - mv test/parse_stl_fuzzer fuzz-testing/fuzzer + $(MAKE) stl_operations_fuzzer -C test CXX=afl-clang++ + mv test/stl_operations_fuzzer fuzz-testing/fuzzer find test/data -size -5k -name *.json | xargs -I{} cp "{}" fuzz-testing/testcases @echo "Execute: afl-fuzz -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer" diff --git a/test/Makefile b/test/Makefile index 5281dacb7b..9ea0d1fb4a 100644 --- a/test/Makefile +++ b/test/Makefile @@ -94,7 +94,7 @@ check: $(OBJECTS) $(TESTCASES) ############################################################################## FUZZER_ENGINE = src/fuzzer-driver_afl.cpp -FUZZERS = parse_afl_fuzzer parse_bson_fuzzer parse_cbor_fuzzer parse_msgpack_fuzzer parse_ubjson_fuzzer parse_stl_fuzzer +FUZZERS = parse_afl_fuzzer parse_bson_fuzzer parse_cbor_fuzzer parse_msgpack_fuzzer parse_ubjson_fuzzer stl_operations_fuzzer fuzzers: $(FUZZERS) parse_afl_fuzzer: @@ -112,5 +112,5 @@ parse_msgpack_fuzzer: parse_ubjson_fuzzer: $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(FUZZER_ENGINE) src/fuzzer-parse_ubjson.cpp -o $@ -parse_stl_fuzzer: - $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(FUZZER_ENGINE) src/fuzzer-parse_stl.cpp -o $@ +stl_operations_fuzzer: + $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(FUZZER_ENGINE) src/fuzzer-stl_operations.cpp -o $@ diff --git a/test/src/fuzzer-parse_stl.cpp b/test/src/fuzzer-parse_stl.cpp deleted file mode 100644 index 6fe87f48cf..0000000000 --- a/test/src/fuzzer-parse_stl.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* - __ _____ _____ _____ - __| | __| | | | JSON for Modern C++ (fuzz test support) -| | |__ | | | | | | version 3.7.3 -|_____|_____|_____|_|___| https://github.com/nlohmann/json - -This file implements a parser test suitable for fuzz testing. Given a byte -array data, it performs the following steps: - -- j1 = parse(data) -- s1 = serialize(j1) -- j2 = parse(s1) -- s2 = serialize(j2) -- assert(s1 == s2) - -The provided function `LLVMFuzzerTestOneInput` can be used in different fuzzer -drivers. - -Licensed under the MIT License . -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using json = nlohmann::json; - -// see http://llvm.org/docs/LibFuzzer.html -extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) -{ - // putting data in several STL containers - std::vector vec(data, data + size); - - // parsing from STL containers - json j_vector(vec); - - try - { - // parse input directly - json j1 = json::parse(data, data + size); - // parse using vector - json j_vec = json::parse(vec); - - // both of them must be equal - assert(j1 == j_vec); - } - catch (const json::parse_error&) - { - // parse errors are ok, because input may be random bytes - } - catch (const json::out_of_range&) - { - // out of range errors may happen if provided sizes are excessive - } - - return 0; -} diff --git a/test/src/fuzzer-stl_operations.cpp b/test/src/fuzzer-stl_operations.cpp new file mode 100644 index 0000000000..93769495d5 --- /dev/null +++ b/test/src/fuzzer-stl_operations.cpp @@ -0,0 +1,140 @@ +/* + __ _____ _____ _____ + __| | __| | | | JSON for Modern C++ (fuzz test support) +| | |__ | | | | | | version 3.7.3 +|_____|_____|_____|_|___| https://github.com/nlohmann/json + +This file implements test for stl operations suitable for fuzz testing. + +The provided function `LLVMFuzzerTestOneInput` can be used in different fuzzer +drivers. + +Licensed under the MIT License . +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using json = nlohmann::json; + +// see http://llvm.org/docs/LibFuzzer.html +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) +{ + // putting data in several STL containers + std::vector vec(data, data + size); + std::deque deq(data, data + size); + std::list lst(data, data + size); + std::forward_list flist(data, data + size); + std::set st(data, data + size); + std::unordered_set uset(data, data + size); + std::multiset multist(data, data + size); + std::unordered_multiset umultiset(data, data + size); + + // parsing from STL containers + json j_vector(vec); + json j_deque(deq); + json j_list(lst); + json j_flist(flist); + json j_set(st); + json j_uset(uset); + json j_multiset(multist); + json j_umultiset(umultiset); + + // json must be same for sequence containers + assert(j_vector == j_deque); + assert(j_vector == j_list); + assert(j_vector == j_flist); + + // iterating json array and testing get() method + for(json::iterator it = j_vector.begin(); it != j_vector.end(); ++it) + { + try + { + int temp = (*it).get(); + } + catch(const json::type_error) + { + // input might not be convertible to integer + } + } + + for(auto& element : j_vector) + { + // range-based iteration + } + + json j_vector2 = json::array(); + json j_vector3 = json::array(); + + for(std::size_t i = 0; i < j_vector.size(); ++i) + { + auto temp = j_vector.at(i); + // testing at() method + j_vector2.push_back(temp); + j_vector3.emplace_back(temp); + // testing push_back and emplace back methods + } + + // these three json vectors must be the same + assert(j_vector == j_vector2); + assert(j_vector == j_vector3); + + std::map mp; + std::unordered_map umap; + std::multimap multimp; + std::unordered_multimap umultimap; + + // converting each consecutive entry in the vector into a key-value pair and adding them to map + for(std::size_t i = 1; i < vec.size(); i+=2) + { + int last_entry = static_cast(vec[i-1]); + std::string key_str = std::to_string(last_entry); + std::pair insert_data = std::make_pair(key_str, vec[i]); + mp.insert(insert_data); + umap.insert(insert_data); + multimp.insert(insert_data); + umultimap.insert(insert_data); + } + + // map -> json map + json j_map(mp); + json j_umap(umap); + json j_multimap(multimp); + json j_umultimap(umultimap); + + // iterating json map + for(json::iterator it = j_map.begin(); it != j_map.end(); ++it) + { + auto temp1 = it.key(); + auto temp2 = it.value(); + } + + try + { + // parse input directly + json j1 = json::parse(data, data + size); + // parse using vector + json j_vec = json::parse(vec); + + // both of them must be equal + assert(j1 == j_vec); + } + catch (const json::parse_error&) + { + // parse errors are ok, because input may be random bytes + } + catch (const json::out_of_range&) + { + // out of range errors may happen if provided sizes are excessive + } + return 0; +}