/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 | 34.1k | { |
16 | 34.1k | try { |
17 | 34.1k | if (!test.isObject()) { |
18 | 216 | return; |
19 | 216 | } |
20 | | |
21 | 33.9k | const AdapterType::Object testObject = test.getObject(); |
22 | 33.9k | const auto dataItr = testObject.find("data"); |
23 | | |
24 | 33.9k | if (dataItr == testObject.end()) { |
25 | 6.00k | return; |
26 | 6.00k | } |
27 | | |
28 | 27.9k | Validator validator(mode); |
29 | 27.9k | ValidationResults results; |
30 | 27.9k | validator.validate(schema, dataItr->second, &results); |
31 | 27.9k | } catch (const std::exception &) { |
32 | 9.33k | } |
33 | 34.1k | } |
34 | | |
35 | | extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) |
36 | 6.53k | { |
37 | 6.53k | AdapterTraits<AdapterType>::DocumentType document; |
38 | 6.53k | document.template Parse<rapidjson::kParseIterativeFlag>(reinterpret_cast<const char *>(data), size); |
39 | | |
40 | 6.53k | if (document.HasParseError() || !document.IsArray()) { |
41 | 1.23k | return 0; |
42 | 1.23k | } |
43 | | |
44 | 21.5k | for (const auto &testCase : AdapterType(document).getArray()) { |
45 | 21.5k | if (!testCase.isObject()) { |
46 | 396 | continue; |
47 | 396 | } |
48 | | |
49 | 21.1k | const AdapterType::Object object = testCase.getObject(); |
50 | 21.1k | const auto schemaItr = object.find("schema"); |
51 | 21.1k | const auto testsItr = object.find("tests"); |
52 | | |
53 | 21.1k | if (schemaItr == object.end() || testsItr == object.end() || |
54 | 21.1k | !testsItr->second.isArray()) { |
55 | 787 | continue; |
56 | 787 | } |
57 | | |
58 | 20.3k | Schema schema; |
59 | 20.3k | SchemaParser parser(size % 2 ? SchemaParser::kDraft4 |
60 | 20.3k | : SchemaParser::kDraft7); |
61 | | |
62 | 20.3k | try { |
63 | 20.3k | parser.populateSchema(schemaItr->second, schema); |
64 | 20.3k | } catch (const std::exception &) { |
65 | 10.0k | continue; |
66 | 10.0k | } |
67 | | |
68 | 10.3k | const auto mode = testsItr->second.hasStrictTypes() |
69 | 10.3k | ? Validator::kStrongTypes |
70 | 10.3k | : Validator::kWeakTypes; |
71 | | |
72 | 34.1k | for (const AdapterType test : testsItr->second.getArray()) { |
73 | 34.1k | runOneTest(test, schema, mode); |
74 | 34.1k | } |
75 | 10.3k | } |
76 | | |
77 | 5.30k | return 0; |
78 | 5.30k | } |