ClickHouse
119 строк · 3.0 Кб
1#include <cstdint>2#include <future>3#include <thread>4#include <utility>5#include <vector>6#include <iostream>7#include <chrono>8
9#include <Poco/Net/PollSet.h>10#include <Poco/Net/SocketAddress.h>11#include <Poco/Net/StreamSocket.h>12
13#include <Interpreters/Context.h>14
15
16int mainEntryClickHouseServer(int argc, char ** argv);17
18static std::string clickhouse("clickhouse-server");19static std::vector<char *> args{clickhouse.data()};20static std::future<int> main_app;21
22static std::string s_host("0.0.0.0");23static char * host = s_host.data();24static int64_t port = 9000;25
26using namespace std::chrono_literals;27
28extern "C"29int LLVMFuzzerInitialize(int * argc, char ***argv)30{
31for (int i = 1; i < *argc; ++i)32{33if ((*argv)[i][0] == '-')34{35if ((*argv)[i][1] == '-')36args.push_back((*argv)[i]);37else38{39if (strncmp((*argv)[i], "-host=", 6) == 0)40{41host = (*argv)[i] + 6;42}43else if (strncmp((*argv)[i], "-port=", 6) == 0)44{45char * p_end = nullptr;46port = strtol((*argv)[i] + 6, &p_end, 10);47}48}49}50}51
52args.push_back(nullptr);53
54main_app = std::async(std::launch::async, mainEntryClickHouseServer, args.size() - 1, args.data());55
56while (!DB::Context::getGlobalContextInstance() || !DB::Context::getGlobalContextInstance()->isServerCompletelyStarted())57{58std::this_thread::sleep_for(100ms);59if (main_app.wait_for(0s) == std::future_status::ready)60exit(-1);61}62
63return 0;64}
65
66extern "C"67int LLVMFuzzerTestOneInput(const uint8_t * data, size_t size)68{
69try70{71if (main_app.wait_for(0s) == std::future_status::ready)72return -1;73
74if (size == 0)75return -1;76
77Poco::Net::SocketAddress address(host, port);78Poco::Net::StreamSocket socket;79
80socket.connectNB(address);81
82Poco::Net::PollSet ps;83ps.add(socket, Poco::Net::PollSet::POLL_READ | Poco::Net::PollSet::POLL_WRITE);84
85std::vector<char> buf(1048576);86size_t sent = 0;87while (true)88{89auto m = ps.poll(Poco::Timespan(1000000));90if (m.empty())91continue;92if (m.begin()->second & Poco::Net::PollSet::POLL_READ)93{94if (int n = socket.receiveBytes(buf.data(), static_cast<int>(buf.size())); n == 0)95{96socket.close();97break;98}99
100continue;101}102
103if (sent < size && m.begin()->second & Poco::Net::PollSet::POLL_WRITE)104{105sent += socket.sendBytes(data + sent, static_cast<int>(size - sent));106if (sent == size)107{108socket.shutdownSend();109continue;110}111}112}113}114catch (...)115{116}117
118return 0;119}
120