/src/ada-url/fuzz/url_pattern.cc
Line | Count | Source |
1 | | #include <fuzzer/FuzzedDataProvider.h> |
2 | | |
3 | | #include <memory> |
4 | | #include <string> |
5 | | |
6 | | #include "ada.cpp" |
7 | | #include "ada.h" |
8 | | |
9 | | using regex_provider = ada::url_pattern_regex::std_regex_provider; |
10 | | |
11 | 3.87k | void exercise_result(auto result) { |
12 | 3.87k | (void)result.get_protocol(); |
13 | 3.87k | (void)result.get_username(); |
14 | 3.87k | (void)result.get_password(); |
15 | 3.87k | (void)result.get_hostname(); |
16 | 3.87k | (void)result.get_port(); |
17 | 3.87k | (void)result.get_pathname(); |
18 | 3.87k | (void)result.get_search(); |
19 | 3.87k | (void)result.get_hash(); |
20 | 3.87k | (void)result.ignore_case(); |
21 | 3.87k | (void)result.has_regexp_groups(); |
22 | 3.87k | } |
23 | | |
24 | 1.29k | extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { |
25 | 7.75k | auto to_ascii = [](const std::string& source) -> std::string { |
26 | 7.75k | std::string result; |
27 | 7.75k | result.reserve(source.size()); |
28 | 28.6k | for (char c : source) { |
29 | 28.6k | result.push_back(static_cast<unsigned char>(c) % 128); |
30 | 28.6k | } |
31 | 7.75k | return result; |
32 | 7.75k | }; |
33 | 1.29k | FuzzedDataProvider fdp(data, size); |
34 | | // We do not want to trigger arbitrary regex matching. |
35 | 1.29k | std::string source_1 = "/" + to_ascii(fdp.ConsumeRandomLengthString(50)) + |
36 | 1.29k | "/" + to_ascii(fdp.ConsumeRandomLengthString(50)); |
37 | 1.29k | std::string base_source_1 = "/" + |
38 | 1.29k | to_ascii(fdp.ConsumeRandomLengthString(50)) + |
39 | 1.29k | "/" + to_ascii(fdp.ConsumeRandomLengthString(50)); |
40 | | |
41 | 1.29k | std::string source_2 = "https://ada-url.com/*"; |
42 | 1.29k | std::string base_source_2 = "https://ada-url.com"; |
43 | | |
44 | 1.29k | std::array<std::pair<std::string, std::string>, 2> sources = {{ |
45 | 1.29k | {source_1, base_source_1}, |
46 | 1.29k | {source_2, base_source_2}, |
47 | 1.29k | }}; |
48 | | |
49 | 2.58k | for (const auto& [source, base_source] : sources) { |
50 | | // Without base or options |
51 | 2.58k | auto result = |
52 | 2.58k | ada::parse_url_pattern<regex_provider>(source, nullptr, nullptr); |
53 | 2.58k | if (result) exercise_result(*result); |
54 | | |
55 | | // Testing with base_url |
56 | 2.58k | std::string_view base_source_view(base_source.data(), base_source.length()); |
57 | 2.58k | auto result_with_base = ada::parse_url_pattern<regex_provider>( |
58 | 2.58k | source, &base_source_view, nullptr); |
59 | 2.58k | if (result_with_base) exercise_result(*result_with_base); |
60 | | |
61 | | // Testing with base_url and options |
62 | 2.58k | ada::url_pattern_options options{.ignore_case = fdp.ConsumeBool()}; |
63 | 2.58k | auto result_with_base_and_options = ada::parse_url_pattern<regex_provider>( |
64 | 2.58k | source, &base_source_view, &options); |
65 | 2.58k | if (result_with_base_and_options) |
66 | 1.29k | exercise_result(*result_with_base_and_options); |
67 | | |
68 | | // Testing with url_pattern_init and base url. |
69 | 2.58k | int field_index = fdp.ConsumeIntegralInRange(0, 7); |
70 | 2.58k | std::string random_value = to_ascii(fdp.ConsumeRandomLengthString(50)); |
71 | 2.58k | ada::url_pattern_init init{}; |
72 | 2.58k | switch (field_index) { |
73 | 2.41k | case 0: |
74 | 2.41k | init.protocol = random_value; |
75 | 2.41k | break; |
76 | 19 | case 1: |
77 | 19 | init.username = random_value; |
78 | 19 | break; |
79 | 28 | case 2: |
80 | 28 | init.password = random_value; |
81 | 28 | break; |
82 | 23 | case 3: |
83 | 23 | init.hostname = random_value; |
84 | 23 | break; |
85 | 37 | case 4: |
86 | 37 | init.port = random_value; |
87 | 37 | break; |
88 | 20 | case 5: |
89 | 20 | init.pathname = random_value; |
90 | 20 | break; |
91 | 17 | case 6: |
92 | 17 | init.search = random_value; |
93 | 17 | break; |
94 | 26 | case 7: |
95 | 26 | init.hash = random_value; |
96 | 26 | break; |
97 | 2.58k | } |
98 | 2.58k | auto result_with_init = ada::parse_url_pattern<regex_provider>( |
99 | 2.58k | init, &base_source_view, nullptr); |
100 | 2.58k | if (result_with_init) exercise_result(*result_with_init); |
101 | 2.58k | } |
102 | | |
103 | 1.29k | return 0; |
104 | 1.29k | } |