mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2025-05-10 09:43:51 +00:00
Merge commit from fork
* fix(parser): Limit line length in getline Prevents potential infinite loop and memory exhaustion in stream_line_reader::getline by enforcing max line length. Signed-off-by: Ville Vesilehto <ville@vesilehto.fi> * fix: increase default max line length to 32k LONG_QUERY_VALUE test is set at 25k. Signed-off-by: Ville Vesilehto <ville@vesilehto.fi> * test(client): expect read error with too long query Adds a test case (`TooLongQueryValue`) to verify client behavior when the request URI is excessively long, exceeding `CPPHTTPLIB_MAX_LINE_LENGTH`. In this scenario, the server is expected to reset the connection. Signed-off-by: Ville Vesilehto <ville@vesilehto.fi> --------- Signed-off-by: Ville Vesilehto <ville@vesilehto.fi>
This commit is contained in:
parent
9589519d58
commit
7b752106ac
@ -145,6 +145,10 @@
|
|||||||
#define CPPHTTPLIB_LISTEN_BACKLOG 5
|
#define CPPHTTPLIB_LISTEN_BACKLOG 5
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef CPPHTTPLIB_MAX_LINE_LENGTH
|
||||||
|
#define CPPHTTPLIB_MAX_LINE_LENGTH 32768
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Headers
|
* Headers
|
||||||
*/
|
*/
|
||||||
@ -3067,6 +3071,11 @@ inline bool stream_line_reader::getline() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (size_t i = 0;; i++) {
|
for (size_t i = 0;; i++) {
|
||||||
|
if (size() >= CPPHTTPLIB_MAX_LINE_LENGTH) {
|
||||||
|
// Treat exceptionally long lines as an error to
|
||||||
|
// prevent infinite loops/memory exhaustion
|
||||||
|
return false;
|
||||||
|
}
|
||||||
char byte;
|
char byte;
|
||||||
auto n = strm_.read(&byte, 1);
|
auto n = strm_.read(&byte, 1);
|
||||||
|
|
||||||
|
15
test/test.cc
15
test/test.cc
@ -43,6 +43,9 @@ const int PORT = 1234;
|
|||||||
const string LONG_QUERY_VALUE = string(25000, '@');
|
const string LONG_QUERY_VALUE = string(25000, '@');
|
||||||
const string LONG_QUERY_URL = "/long-query-value?key=" + LONG_QUERY_VALUE;
|
const string LONG_QUERY_URL = "/long-query-value?key=" + LONG_QUERY_VALUE;
|
||||||
|
|
||||||
|
const string TOO_LONG_QUERY_VALUE = string(35000, '@');
|
||||||
|
const string TOO_LONG_QUERY_URL = "/too-long-query-value?key=" + TOO_LONG_QUERY_VALUE;
|
||||||
|
|
||||||
const std::string JSON_DATA = "{\"hello\":\"world\"}";
|
const std::string JSON_DATA = "{\"hello\":\"world\"}";
|
||||||
|
|
||||||
const string LARGE_DATA = string(1024 * 1024 * 100, '@'); // 100MB
|
const string LARGE_DATA = string(1024 * 1024 * 100, '@'); // 100MB
|
||||||
@ -2867,6 +2870,11 @@ protected:
|
|||||||
EXPECT_EQ(LONG_QUERY_URL, req.target);
|
EXPECT_EQ(LONG_QUERY_URL, req.target);
|
||||||
EXPECT_EQ(LONG_QUERY_VALUE, req.get_param_value("key"));
|
EXPECT_EQ(LONG_QUERY_VALUE, req.get_param_value("key"));
|
||||||
})
|
})
|
||||||
|
.Get("/too-long-query-value",
|
||||||
|
[&](const Request &req, Response & /*res*/) {
|
||||||
|
EXPECT_EQ(TOO_LONG_QUERY_URL, req.target);
|
||||||
|
EXPECT_EQ(TOO_LONG_QUERY_VALUE, req.get_param_value("key"));
|
||||||
|
})
|
||||||
.Get("/array-param",
|
.Get("/array-param",
|
||||||
[&](const Request &req, Response & /*res*/) {
|
[&](const Request &req, Response & /*res*/) {
|
||||||
EXPECT_EQ(3u, req.get_param_value_count("array"));
|
EXPECT_EQ(3u, req.get_param_value_count("array"));
|
||||||
@ -3655,6 +3663,13 @@ TEST_F(ServerTest, LongQueryValue) {
|
|||||||
EXPECT_EQ(StatusCode::UriTooLong_414, res->status);
|
EXPECT_EQ(StatusCode::UriTooLong_414, res->status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ServerTest, TooLongQueryValue) {
|
||||||
|
auto res = cli_.Get(TOO_LONG_QUERY_URL.c_str());
|
||||||
|
|
||||||
|
ASSERT_FALSE(res);
|
||||||
|
EXPECT_EQ(Error::Read, res.error());
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(ServerTest, TooLongHeader) {
|
TEST_F(ServerTest, TooLongHeader) {
|
||||||
Request req;
|
Request req;
|
||||||
req.method = "GET";
|
req.method = "GET";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user