| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- #include <cstdint>
- #include <cstring>
- #include <httplib.h>
- class FuzzedStream : public httplib::Stream {
- public:
- FuzzedStream(const uint8_t *data, size_t size)
- : data_(data), size_(size), read_pos_(0) {}
- ssize_t read(char *ptr, size_t size) override {
- if (size + read_pos_ > size_) { size = size_ - read_pos_; }
- memcpy(ptr, data_ + read_pos_, size);
- read_pos_ += size;
- return static_cast<ssize_t>(size);
- }
- ssize_t write(const char *ptr, size_t size) override {
- request_.append(ptr, size);
- return static_cast<ssize_t>(size);
- }
- ssize_t write(const char *ptr) { return write(ptr, strlen(ptr)); }
- ssize_t write(const std::string &s) { return write(s.data(), s.size()); }
- bool is_readable() const override { return true; }
- bool wait_readable() const override { return true; }
- bool wait_writable() const override { return true; }
- void get_remote_ip_and_port(std::string &ip, int &port) const override {
- ip = "127.0.0.1";
- port = 8080;
- }
- void get_local_ip_and_port(std::string &ip, int &port) const override {
- ip = "127.0.0.1";
- port = 8080;
- }
- socket_t socket() const override { return 0; }
- time_t duration() const override { return 0; };
- private:
- const uint8_t *data_;
- size_t size_;
- size_t read_pos_;
- std::string request_;
- };
- class FuzzableClient : public httplib::ClientImpl {
- public:
- FuzzableClient() : httplib::ClientImpl("localhost", 8080) {}
- void ProcessFuzzedResponse(FuzzedStream &stream, const std::string &method) {
- httplib::Request req;
- req.method = method;
- req.path = "/";
- httplib::Response res;
- bool close_connection = false;
- httplib::Error error = httplib::Error::Success;
- process_request(stream, req, res, close_connection, error);
- }
- };
- extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
- if (size < 1) return 0;
- FuzzedStream stream{data + 1, size - 1};
- FuzzableClient client;
- // Use the first byte to select method
- std::string method;
- switch (data[0] % 6) {
- case 0: method = "GET"; break;
- case 1: method = "POST"; break;
- case 2: method = "PUT"; break;
- case 3: method = "PATCH"; break;
- case 4: method = "DELETE"; break;
- case 5: method = "OPTIONS"; break;
- }
- client.ProcessFuzzedResponse(stream, method);
- return 0;
- }
|