/src/valijson/tests/fuzzing/fuzzer.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | #include <valijson/adapters/rapidjson_adapter.hpp> |
2 | | #include <valijson/schema_parser.hpp> |
3 | | #include <valijson/validator.hpp> |
4 | | |
5 | | using valijson::Schema; |
6 | | using valijson::SchemaParser; |
7 | | using valijson::ValidationResults; |
8 | | using valijson::Validator; |
9 | | using valijson::adapters::AdapterTraits; |
10 | | using valijson::adapters::RapidJsonAdapter; |
11 | | using AdapterType = RapidJsonAdapter; |
12 | | |
13 | | void runOneTest(const AdapterType &test, const Schema &schema, |
14 | | Validator::TypeCheckingMode mode) |
15 | 76.7k | { |
16 | 76.7k | try { |
17 | 76.7k | if (!test.isObject()) { |
18 | 1.28k | return; |
19 | 1.28k | } |
20 | | |
21 | 75.4k | const AdapterType::Object testObject = test.getObject(); |
22 | 75.4k | const auto dataItr = testObject.find("data"); |
23 | | |
24 | 75.4k | if (dataItr == testObject.end()) { |
25 | 9.72k | return; |
26 | 9.72k | } |
27 | | |
28 | 65.7k | Validator validator(mode); |
29 | 65.7k | ValidationResults results; |
30 | 65.7k | validator.validate(schema, dataItr->second, &results); |
31 | 65.7k | } catch (const std::exception &) { |
32 | 14.3k | } |
33 | 76.7k | } |
34 | | |
35 | | extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) |
36 | 16.7k | { |
37 | 16.7k | AdapterTraits<AdapterType>::DocumentType document; |
38 | 16.7k | document.template Parse<rapidjson::kParseIterativeFlag>(reinterpret_cast<const char *>(data), size); |
39 | | |
40 | 16.7k | if (document.HasParseError() || !document.IsArray()) { |
41 | 2.44k | return 0; |
42 | 2.44k | } |
43 | | |
44 | 53.2k | for (const auto &testCase : AdapterType(document).getArray()) { |
45 | 53.2k | if (!testCase.isObject()) { |
46 | 1.30k | continue; |
47 | 1.30k | } |
48 | | |
49 | 51.9k | const AdapterType::Object object = testCase.getObject(); |
50 | 51.9k | const auto schemaItr = object.find("schema"); |
51 | 51.9k | const auto testsItr = object.find("tests"); |
52 | | |
53 | 51.9k | if (schemaItr == object.end() || testsItr == object.end() || |
54 | 51.9k | !testsItr->second.isArray()) { |
55 | 2.52k | continue; |
56 | 2.52k | } |
57 | | |
58 | 49.4k | Schema schema; |
59 | 49.4k | SchemaParser parser(size % 2 ? SchemaParser::kDraft4 |
60 | 49.4k | : SchemaParser::kDraft7); |
61 | | |
62 | 49.4k | try { |
63 | 49.4k | parser.populateSchema(schemaItr->second, schema); |
64 | 49.4k | } catch (const std::exception &) { |
65 | 25.9k | continue; |
66 | 25.9k | } |
67 | | |
68 | 23.4k | const auto mode = testsItr->second.hasStrictTypes() |
69 | 23.4k | ? Validator::kStrongTypes |
70 | 23.4k | : Validator::kWeakTypes; |
71 | | |
72 | 76.7k | for (const AdapterType test : testsItr->second.getArray()) { |
73 | 76.7k | runOneTest(test, schema, mode); |
74 | 76.7k | } |
75 | 23.4k | } |
76 | | |
77 | 14.3k | return 0; |
78 | 14.3k | } |