1
0
mirror of synced 2025-04-19 00:24:02 +03:00
This commit is contained in:
yhirose 2025-02-05 12:46:33 -05:00 committed by GitHub
parent 9bbb4741b4
commit 4941d5b56b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 29 additions and 20 deletions

View File

@ -2549,7 +2549,7 @@ inline bool is_obs_text(char c) { return 128 <= static_cast<unsigned char>(c); }
inline bool is_field_vchar(char c) { return is_vchar(c) || is_obs_text(c); } inline bool is_field_vchar(char c) { return is_vchar(c) || is_obs_text(c); }
inline bool is_field_content(const std::string &s) { inline bool is_field_content(const std::string &s) {
if (s.empty()) { return false; } if (s.empty()) { return true; }
if (s.size() == 1) { if (s.size() == 1) {
return is_field_vchar(s[0]); return is_field_vchar(s[0]);
@ -4214,22 +4214,21 @@ inline bool parse_header(const char *beg, const char *end, T fn) {
if (!key_len) { return false; } if (!key_len) { return false; }
auto key = std::string(beg, key_end); auto key = std::string(beg, key_end);
auto val = case_ignore::equal(key, "Location") // auto val = (case_ignore::equal(key, "Location") ||
? std::string(p, end) // case_ignore::equal(key, "Referer"))
: decode_url(std::string(p, end), false); // ? std::string(p, end)
// : decode_url(std::string(p, end), false);
auto val = std::string(p, end);
// NOTE: From RFC 9110: if (!detail::fields::is_field_value(val)) { return false; }
// Field values containing CR, LF, or NUL characters are
// invalid and dangerous, due to the varying ways that if (case_ignore::equal(key, "Location") ||
// implementations might parse and interpret those case_ignore::equal(key, "Referer")) {
// characters; a recipient of CR, LF, or NUL within a field fn(key, val);
// value MUST either reject the message or replace each of } else {
// those characters with SP before further processing or fn(key, decode_url(val, false));
// forwarding of that message. }
static const std::string CR_LF_NUL("\r\n\0", 3);
if (val.find_first_of(CR_LF_NUL) != std::string::npos) { return false; }
fn(key, val);
return true; return true;
} }
@ -4265,7 +4264,7 @@ inline bool read_headers(Stream &strm, Headers &headers) {
auto end = line_reader.ptr() + line_reader.size() - line_terminator_len; auto end = line_reader.ptr() + line_reader.size() - line_terminator_len;
if (!parse_header(line_reader.ptr(), end, if (!parse_header(line_reader.ptr(), end,
[&](const std::string &key, std::string &val) { [&](const std::string &key, const std::string &val) {
headers.emplace(key, val); headers.emplace(key, val);
})) { })) {
return false; return false;

View File

@ -1866,7 +1866,7 @@ TEST(PathUrlEncodeTest, PathUrlEncode) {
TEST(PathUrlEncodeTest, IncludePercentEncodingLF) { TEST(PathUrlEncodeTest, IncludePercentEncodingLF) {
Server svr; Server svr;
svr.Get("/", [](const Request &req, Response &res) { svr.Get("/", [](const Request &req, Response &) {
EXPECT_EQ("\x0A", req.get_param_value("something")); EXPECT_EQ("\x0A", req.get_param_value("something"));
}); });
@ -4936,8 +4936,10 @@ TEST(ServerRequestParsingTest, TrimWhitespaceFromHeaderValues) {
"Connection: close\r\n" "Connection: close\r\n"
"\r\n"; "\r\n";
ASSERT_TRUE(send_request(5, req)); std::string res;
EXPECT_EQ(header_value, "\v bar \x1B"); ASSERT_TRUE(send_request(5, req, &res));
EXPECT_EQ(header_value, "");
EXPECT_EQ("HTTP/1.1 400 Bad Request", res.substr(0, 24));
} }
// Sends a raw request and verifies that there isn't a crash or exception. // Sends a raw request and verifies that there isn't a crash or exception.
@ -5095,6 +5097,14 @@ TEST(ServerRequestParsingTest, InvalidFieldValueContains_CR_LF_NUL) {
EXPECT_EQ("HTTP/1.1 400 Bad Request", out.substr(0, 24)); EXPECT_EQ("HTTP/1.1 400 Bad Request", out.substr(0, 24));
} }
TEST(ServerRequestParsingTest, InvalidFieldValueContains_LF) {
std::string out;
std::string request(
"GET /header_field_value_check HTTP/1.1\r\nTest: [\n\n\n]\r\n\r\n", 55);
test_raw_request(request, &out);
EXPECT_EQ("HTTP/1.1 400 Bad Request", out.substr(0, 24));
}
TEST(ServerRequestParsingTest, EmptyFieldValue) { TEST(ServerRequestParsingTest, EmptyFieldValue) {
std::string out; std::string out;
@ -7984,7 +7994,7 @@ TEST(InvalidHeaderCharsTest, is_field_value) {
EXPECT_FALSE(detail::fields::is_field_value(" example_token")); EXPECT_FALSE(detail::fields::is_field_value(" example_token"));
EXPECT_FALSE(detail::fields::is_field_value("example_token ")); EXPECT_FALSE(detail::fields::is_field_value("example_token "));
EXPECT_TRUE(detail::fields::is_field_value("token@123")); EXPECT_TRUE(detail::fields::is_field_value("token@123"));
EXPECT_FALSE(detail::fields::is_field_value("")); EXPECT_TRUE(detail::fields::is_field_value(""));
EXPECT_FALSE(detail::fields::is_field_value("example\rtoken")); EXPECT_FALSE(detail::fields::is_field_value("example\rtoken"));
EXPECT_FALSE(detail::fields::is_field_value("example\ntoken")); EXPECT_FALSE(detail::fields::is_field_value("example\ntoken"));
EXPECT_FALSE(detail::fields::is_field_value(std::string("\0", 1))); EXPECT_FALSE(detail::fields::is_field_value(std::string("\0", 1)));