/src/valijson/tests/fuzzing/fuzzer.cpp
Line | Count | Source |
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 | 37.5k | { |
16 | 37.5k | try { |
17 | 37.5k | if (!test.isObject()) { |
18 | 405 | return; |
19 | 405 | } |
20 | | |
21 | 37.1k | const AdapterType::Object testObject = test.getObject(); |
22 | 37.1k | const auto dataItr = testObject.find("data"); |
23 | | |
24 | 37.1k | if (dataItr == testObject.end()) { |
25 | 7.92k | return; |
26 | 7.92k | } |
27 | | |
28 | 29.2k | Validator validator(mode); |
29 | 29.2k | ValidationResults results; |
30 | 29.2k | validator.validate(schema, dataItr->second, &results); |
31 | 29.2k | } catch (const std::exception &) { |
32 | 9.31k | } |
33 | 37.5k | } |
34 | | |
35 | | extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) |
36 | 7.01k | { |
37 | 7.01k | AdapterTraits<AdapterType>::DocumentType document; |
38 | 7.01k | document.template Parse<rapidjson::kParseIterativeFlag>(reinterpret_cast<const char *>(data), size); |
39 | | |
40 | 7.01k | if (document.HasParseError() || !document.IsArray()) { |
41 | 1.28k | return 0; |
42 | 1.28k | } |
43 | | |
44 | 26.2k | for (const auto &testCase : AdapterType(document).getArray()) { |
45 | 26.2k | if (!testCase.isObject()) { |
46 | 252 | continue; |
47 | 252 | } |
48 | | |
49 | 25.9k | const AdapterType::Object object = testCase.getObject(); |
50 | 25.9k | const auto schemaItr = object.find("schema"); |
51 | 25.9k | const auto testsItr = object.find("tests"); |
52 | | |
53 | 25.9k | if (schemaItr == object.end() || testsItr == object.end() || |
54 | 24.9k | !testsItr->second.isArray()) { |
55 | 1.06k | continue; |
56 | 1.06k | } |
57 | | |
58 | 24.9k | Schema schema; |
59 | 24.9k | SchemaParser parser(size % 2 ? SchemaParser::kDraft4 |
60 | 24.9k | : SchemaParser::kDraft7); |
61 | | |
62 | 24.9k | try { |
63 | 24.9k | parser.populateSchema(schemaItr->second, schema); |
64 | 24.9k | } catch (const std::exception &) { |
65 | 13.0k | continue; |
66 | 13.0k | } |
67 | | |
68 | 11.8k | const auto mode = testsItr->second.hasStrictTypes() |
69 | 11.8k | ? Validator::kStrongTypes |
70 | 11.8k | : Validator::kWeakTypes; |
71 | | |
72 | 37.5k | for (const AdapterType test : testsItr->second.getArray()) { |
73 | 37.5k | runOneTest(test, schema, mode); |
74 | 37.5k | } |
75 | 11.8k | } |
76 | | |
77 | 5.72k | return 0; |
78 | 5.72k | } |