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