From 0ff2e16d69a315990c7232be06a636dac3c467e5 Mon Sep 17 00:00:00 2001 From: yhirose Date: Sat, 21 Jan 2023 01:07:21 -0500 Subject: [PATCH] Issue 52666: cpp-httplib:server_fuzzer: Timeout in server_fuzzer --- httplib.h | 3 ++ ...e-minimized-server_fuzzer-5042094968537088 | Bin test/test.cc | 43 ++++++++++++++++++ 3 files changed, 46 insertions(+) rename test/{ => fuzzing/corpus}/clusterfuzz-testcase-minimized-server_fuzzer-5042094968537088 (100%) diff --git a/httplib.h b/httplib.h index e4a1dba..3c01e16 100644 --- a/httplib.h +++ b/httplib.h @@ -3960,6 +3960,9 @@ public: if (std::regex_match(header, m, re_content_disposition)) { file_.name = m[1]; file_.filename = m[2]; + } else { + is_valid_ = false; + return false; } } buf_erase(pos + crlf_.size()); diff --git a/test/clusterfuzz-testcase-minimized-server_fuzzer-5042094968537088 b/test/fuzzing/corpus/clusterfuzz-testcase-minimized-server_fuzzer-5042094968537088 similarity index 100% rename from test/clusterfuzz-testcase-minimized-server_fuzzer-5042094968537088 rename to test/fuzzing/corpus/clusterfuzz-testcase-minimized-server_fuzzer-5042094968537088 diff --git a/test/test.cc b/test/test.cc index 01fe2e5..2c5ad4f 100644 --- a/test/test.cc +++ b/test/test.cc @@ -5344,6 +5344,49 @@ TEST(MultipartFormDataTest, DataProviderItems) { t.join(); } +TEST(MultipartFormDataTest, BadHeader) { + Server svr; + svr.Post("/post", [&](const Request & /*req*/, Response &res) { + res.set_content("ok", "text/plain"); + }); + + thread t = thread([&] { svr.listen(HOST, PORT); }); + while (!svr.is_running()) { + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + + const std::string body = + "This is the preamble. It is to be ignored, though it\r\n" + "is a handy place for composition agents to include an\r\n" + "explanatory note to non-MIME conformant readers.\r\n" + "\r\n" + "\r\n" + "--simple boundary\r\n" + "Content-Disposition: form-data; name=\"field1\"\r\n" + ": BAD...\r\n" + "\r\n" + "value1\r\n" + "--simple boundary\r\n" + "Content-Disposition: form-data; name=\"field2\"; " + "filename=\"example.txt\"\r\n" + "\r\n" + "value2\r\n" + "--simple boundary--\r\n" + "This is the epilogue. It is also to be ignored.\r\n"; + + std::string content_type = + R"(multipart/form-data; boundary="simple boundary")"; + + Client cli(HOST, PORT); + auto res = cli.Post("/post", body, content_type.c_str()); + + ASSERT_TRUE(res); + EXPECT_EQ(400, res->status); + + svr.stop(); + t.join(); +} + TEST(MultipartFormDataTest, WithPreamble) { Server svr; svr.Post("/post", [&](const Request & /*req*/, Response &res) {