/src/cpp-httplib/test/fuzzing/server_fuzzer.cc
Line | Count | Source (jump to first uncovered line) |
1 | | #include <cstdint> |
2 | | |
3 | | #include <httplib.h> |
4 | | |
5 | | class FuzzedStream : public httplib::Stream { |
6 | | public: |
7 | | FuzzedStream(const uint8_t *data, size_t size) |
8 | 5.77k | : data_(data), size_(size), read_pos_(0) {} |
9 | | |
10 | 3.05M | ssize_t read(char *ptr, size_t size) override { |
11 | 3.05M | if (size + read_pos_ > size_) { size = size_ - read_pos_; } |
12 | 3.05M | memcpy(ptr, data_ + read_pos_, size); |
13 | 3.05M | read_pos_ += size; |
14 | 3.05M | return static_cast<ssize_t>(size); |
15 | 3.05M | } |
16 | | |
17 | 7.32k | ssize_t write(const char *ptr, size_t size) override { |
18 | 7.32k | response_.append(ptr, size); |
19 | 7.32k | return static_cast<int>(size); |
20 | 7.32k | } |
21 | | |
22 | 0 | ssize_t write(const char *ptr) { return write(ptr, strlen(ptr)); } |
23 | | |
24 | 0 | ssize_t write(const std::string &s) { return write(s.data(), s.size()); } |
25 | | |
26 | 0 | bool is_readable() const override { return true; } |
27 | | |
28 | 0 | bool wait_readable() const override { return true; } |
29 | | |
30 | 0 | bool wait_writable() const override { return true; } |
31 | | |
32 | 0 | void get_remote_ip_and_port(std::string &ip, int &port) const override { |
33 | 0 | ip = "127.0.0.1"; |
34 | 0 | port = 8080; |
35 | 0 | } |
36 | | |
37 | 0 | void get_local_ip_and_port(std::string &ip, int &port) const override { |
38 | 0 | ip = "127.0.0.1"; |
39 | 0 | port = 8080; |
40 | 0 | } |
41 | | |
42 | 4.15k | socket_t socket() const override { return 0; } |
43 | | |
44 | 0 | time_t duration() const override { return 0; }; |
45 | | |
46 | | private: |
47 | | const uint8_t *data_; |
48 | | size_t size_; |
49 | | size_t read_pos_; |
50 | | std::string response_; |
51 | | }; |
52 | | |
53 | | class FuzzableServer : public httplib::Server { |
54 | | public: |
55 | 5.77k | void ProcessFuzzedRequest(FuzzedStream &stream) { |
56 | 5.77k | bool connection_close = false; |
57 | 5.77k | process_request(stream, |
58 | 5.77k | /*remote_addr=*/"", |
59 | 5.77k | /*remote_port =*/0, |
60 | 5.77k | /*local_addr=*/"", |
61 | 5.77k | /*local_port =*/0, |
62 | 5.77k | /*last_connection=*/false, connection_close, nullptr); |
63 | 5.77k | } |
64 | | }; |
65 | | |
66 | | static FuzzableServer g_server; |
67 | | |
68 | 2 | extern "C" int LLVMFuzzerInitialize(int * /*argc*/, char *** /*argv*/) { |
69 | 2 | g_server.Get(R"(.*)", |
70 | 704 | [&](const httplib::Request & /*req*/, httplib::Response &res) { |
71 | 704 | res.set_content("response content", "text/plain"); |
72 | 704 | }); |
73 | 2 | g_server.Post(R"(.*)", |
74 | 12 | [&](const httplib::Request & /*req*/, httplib::Response &res) { |
75 | 12 | res.set_content("response content", "text/plain"); |
76 | 12 | }); |
77 | 2 | g_server.Put(R"(.*)", |
78 | 1.23k | [&](const httplib::Request & /*req*/, httplib::Response &res) { |
79 | 1.23k | res.set_content("response content", "text/plain"); |
80 | 1.23k | }); |
81 | 2 | g_server.Patch(R"(.*)", |
82 | 2 | [&](const httplib::Request & /*req*/, httplib::Response &res) { |
83 | 1 | res.set_content("response content", "text/plain"); |
84 | 1 | }); |
85 | 2 | g_server.Delete( |
86 | 5 | R"(.*)", [&](const httplib::Request & /*req*/, httplib::Response &res) { |
87 | 5 | res.set_content("response content", "text/plain"); |
88 | 5 | }); |
89 | 2 | g_server.Options( |
90 | 2 | R"(.*)", [&](const httplib::Request & /*req*/, httplib::Response &res) { |
91 | 1 | res.set_content("response content", "text/plain"); |
92 | 1 | }); |
93 | 2 | return 0; |
94 | 2 | } |
95 | | |
96 | 5.77k | extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { |
97 | 5.77k | FuzzedStream stream{data, size}; |
98 | 5.77k | g_server.ProcessFuzzedRequest(stream); |
99 | 5.77k | return 0; |
100 | 5.77k | } |