Coverage Report

Created: 2026-02-14 06:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cpp-httplib/test/fuzzing/server_fuzzer.cc
Line
Count
Source
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.75k
      : data_(data), size_(size), read_pos_(0) {}
9
10
2.49M
  ssize_t read(char *ptr, size_t size) override {
11
2.49M
    if (size + read_pos_ > size_) { size = size_ - read_pos_; }
12
2.49M
    memcpy(ptr, data_ + read_pos_, size);
13
2.49M
    read_pos_ += size;
14
2.49M
    return static_cast<ssize_t>(size);
15
2.49M
  }
16
17
7.14k
  ssize_t write(const char *ptr, size_t size) override {
18
7.14k
    response_.append(ptr, size);
19
7.14k
    return static_cast<int>(size);
20
7.14k
  }
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
1.09k
  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
3.94k
  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.75k
  void ProcessFuzzedRequest(FuzzedStream &stream) {
56
5.75k
    bool connection_close = false;
57
5.75k
    process_request(stream,
58
5.75k
                    /*remote_addr=*/"",
59
5.75k
                    /*remote_port =*/0,
60
5.75k
                    /*local_addr=*/"",
61
5.75k
                    /*local_port =*/0,
62
5.75k
                    /*last_connection=*/false, connection_close, nullptr);
63
5.75k
  }
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
701
               [&](const httplib::Request & /*req*/, httplib::Response &res) {
71
701
                 res.set_content("response content", "text/plain");
72
701
               });
73
2
  g_server.Post(R"(.*)",
74
18
                [&](const httplib::Request & /*req*/, httplib::Response &res) {
75
18
                  res.set_content("response content", "text/plain");
76
18
                });
77
2
  g_server.Put(R"(.*)",
78
1.02k
               [&](const httplib::Request & /*req*/, httplib::Response &res) {
79
1.02k
                 res.set_content("response content", "text/plain");
80
1.02k
               });
81
2
  g_server.Patch(R"(.*)",
82
2
                 [&](const httplib::Request & /*req*/, httplib::Response &res) {
83
2
                   res.set_content("response content", "text/plain");
84
2
                 });
85
2
  g_server.Delete(
86
3
      R"(.*)", [&](const httplib::Request & /*req*/, httplib::Response &res) {
87
3
        res.set_content("response content", "text/plain");
88
3
      });
89
2
  g_server.Options(
90
6
      R"(.*)", [&](const httplib::Request & /*req*/, httplib::Response &res) {
91
6
        res.set_content("response content", "text/plain");
92
6
      });
93
2
  return 0;
94
2
}
95
96
5.75k
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
97
5.75k
  FuzzedStream stream{data, size};
98
5.75k
  g_server.ProcessFuzzedRequest(stream);
99
5.75k
  return 0;
100
5.75k
}