1 // __ _____ _____ _____
2 // __| | __| | | | JSON for Modern C++ (supporting code)
3 // | | |__ | | | | | | version 3.11.2
4 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
5 //
6 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
7 // SPDX-License-Identifier: MIT
8
9 /*
10 This file implements a parser test suitable for fuzz testing. Given a byte
11 array data, it performs the following steps:
12
13 - j1 = from_bjdata(data)
14 - vec = to_bjdata(j1)
15 - j2 = from_bjdata(vec)
16 - assert(j1 == j2)
17 - vec2 = to_bjdata(j1, use_size = true, use_type = false)
18 - j3 = from_bjdata(vec2)
19 - assert(j1 == j3)
20 - vec3 = to_bjdata(j1, use_size = true, use_type = true)
21 - j4 = from_bjdata(vec3)
22 - assert(j1 == j4)
23
24 The provided function `LLVMFuzzerTestOneInput` can be used in different fuzzer
25 drivers.
26 */
27
28 #include <iostream>
29 #include <sstream>
30 #include <nlohmann/json.hpp>
31
32 using json = nlohmann::json;
33
34 // see http://llvm.org/docs/LibFuzzer.html
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)35 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
36 {
37 try
38 {
39 // step 1: parse input
40 std::vector<uint8_t> vec1(data, data + size);
41 json j1 = json::from_bjdata(vec1);
42
43 try
44 {
45 // step 2.1: round trip without adding size annotations to container types
46 std::vector<uint8_t> vec2 = json::to_bjdata(j1, false, false);
47
48 // step 2.2: round trip with adding size annotations but without adding type annonations to container types
49 std::vector<uint8_t> vec3 = json::to_bjdata(j1, true, false);
50
51 // step 2.3: round trip with adding size as well as type annotations to container types
52 std::vector<uint8_t> vec4 = json::to_bjdata(j1, true, true);
53
54 // parse serialization
55 json j2 = json::from_bjdata(vec2);
56 json j3 = json::from_bjdata(vec3);
57 json j4 = json::from_bjdata(vec4);
58
59 // serializations must match
60 assert(json::to_bjdata(j2, false, false) == vec2);
61 assert(json::to_bjdata(j3, true, false) == vec3);
62 assert(json::to_bjdata(j4, true, true) == vec4);
63 }
64 catch (const json::parse_error&)
65 {
66 // parsing a BJData serialization must not fail
67 assert(false);
68 }
69 }
70 catch (const json::parse_error&)
71 {
72 // parse errors are ok, because input may be random bytes
73 }
74 catch (const json::type_error&)
75 {
76 // type errors can occur during parsing, too
77 }
78 catch (const json::out_of_range&)
79 {
80 // out of range errors may happen if provided sizes are excessive
81 }
82
83 // return 0 - non-zero return values are reserved for future use
84 return 0;
85 }
86