From 1399abc58371978814e62b5eadc281ccbeb8dc96 Mon Sep 17 00:00:00 2001
From: Niels Lohmann <niels.lohmann@gmail.com>
Date: Sun, 25 Dec 2016 16:18:56 +0100
Subject: [PATCH] :construction: added MessagePack fuzz target

---
 Makefile                          |  8 ++++
 test/Makefile                     |  3 ++
 test/src/fuzzer-parse_msgpack.cpp | 68 +++++++++++++++++++++++++++++++
 3 files changed, 79 insertions(+)
 create mode 100644 test/src/fuzzer-parse_msgpack.cpp

diff --git a/Makefile b/Makefile
index 76e60170..8f196950 100644
--- a/Makefile
+++ b/Makefile
@@ -62,6 +62,14 @@ fuzz_testing_cbor:
 	find test/data -size -5k -name *.cbor | 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_msgpack_fuzzer -C test CXX=afl-clang++
+	mv test/parse_msgpack_fuzzer fuzz-testing/fuzzer
+	find test/data -size -5k -name *.msgpack | xargs -I{} cp "{}" fuzz-testing/testcases
+	@echo "Execute: afl-fuzz -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer"
+
 
 ##########################################################################
 # static analyzer
diff --git a/test/Makefile b/test/Makefile
index a063221a..556ab0d7 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -89,3 +89,6 @@ parse_afl_fuzzer:
 
 parse_cbor_fuzzer:
 	$(CXX) $(CXXFLAGS) $(CPPFLAGS) src/fuzzer-driver_afl.cpp src/fuzzer-parse_cbor.cpp -o $@
+
+parse_msgpack_fuzzer:
+	$(CXX) $(CXXFLAGS) $(CPPFLAGS) src/fuzzer-driver_afl.cpp src/fuzzer-parse_msgpack.cpp -o $@
diff --git a/test/src/fuzzer-parse_msgpack.cpp b/test/src/fuzzer-parse_msgpack.cpp
new file mode 100644
index 00000000..992697c2
--- /dev/null
+++ b/test/src/fuzzer-parse_msgpack.cpp
@@ -0,0 +1,68 @@
+/*
+    __ _____ _____ _____
+ __|  |   __|     |   | |  JSON for Modern C++ (fuzz test support)
+|  |  |__   |  |  | | | |  version 2.0.9
+|_____|_____|_____|_|___|  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_msgpack(data)
+- vec = to_msgpack(j1)
+- j2 = from_msgpack(vec)
+- assert(j1 == j2)
+
+The provided function `LLVMFuzzerTestOneInput` can be used in different fuzzer
+drivers.
+
+Licensed under the MIT License <http://opensource.org/licenses/MIT>.
+*/
+
+#include <iostream>
+#include <sstream>
+#include <json.hpp>
+
+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<uint8_t> vec1(data, data + size);
+        json j1 = json::from_msgpack(vec1);
+
+        try
+        {
+            // step 2: round trip
+            std::vector<uint8_t> vec2 = json::to_msgpack(j1);
+
+            // parse serialization
+            json j2 = json::from_msgpack(vec2);
+
+            // deserializations must match
+            assert(j1 == j2);
+        }
+        catch (const std::invalid_argument&)
+        {
+            // parsing a MessagePack serialization must not fail
+            assert(false);
+        }
+    }
+    catch (const std::invalid_argument&)
+    {
+        // parse errors are ok, because input may be random bytes
+    }
+    catch (const std::out_of_range&)
+    {
+        // parse errors are ok, because input may be random bytes
+    }
+    catch (const std::domain_error&)
+    {
+        // parse errors are ok, because input may be random bytes
+    }
+
+    // return 0 - non-zero return values are reserved for future use
+    return 0;
+}