parent
9bbb4741b4
commit
4941d5b56b
31
httplib.h
31
httplib.h
@ -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_content(const std::string &s) {
|
||||
if (s.empty()) { return false; }
|
||||
if (s.empty()) { return true; }
|
||||
|
||||
if (s.size() == 1) {
|
||||
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; }
|
||||
|
||||
auto key = std::string(beg, key_end);
|
||||
auto val = case_ignore::equal(key, "Location")
|
||||
? std::string(p, end)
|
||||
: decode_url(std::string(p, end), false);
|
||||
// auto val = (case_ignore::equal(key, "Location") ||
|
||||
// case_ignore::equal(key, "Referer"))
|
||||
// ? std::string(p, end)
|
||||
// : decode_url(std::string(p, end), false);
|
||||
auto val = std::string(p, end);
|
||||
|
||||
// NOTE: From RFC 9110:
|
||||
// Field values containing CR, LF, or NUL characters are
|
||||
// invalid and dangerous, due to the varying ways that
|
||||
// implementations might parse and interpret those
|
||||
// characters; a recipient of CR, LF, or NUL within a field
|
||||
// value MUST either reject the message or replace each of
|
||||
// those characters with SP before further processing or
|
||||
// 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; }
|
||||
if (!detail::fields::is_field_value(val)) { return false; }
|
||||
|
||||
if (case_ignore::equal(key, "Location") ||
|
||||
case_ignore::equal(key, "Referer")) {
|
||||
fn(key, val);
|
||||
} else {
|
||||
fn(key, decode_url(val, false));
|
||||
}
|
||||
|
||||
fn(key, val);
|
||||
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;
|
||||
|
||||
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);
|
||||
})) {
|
||||
return false;
|
||||
|
18
test/test.cc
18
test/test.cc
@ -1866,7 +1866,7 @@ TEST(PathUrlEncodeTest, PathUrlEncode) {
|
||||
TEST(PathUrlEncodeTest, IncludePercentEncodingLF) {
|
||||
Server svr;
|
||||
|
||||
svr.Get("/", [](const Request &req, Response &res) {
|
||||
svr.Get("/", [](const Request &req, Response &) {
|
||||
EXPECT_EQ("\x0A", req.get_param_value("something"));
|
||||
});
|
||||
|
||||
@ -4936,8 +4936,10 @@ TEST(ServerRequestParsingTest, TrimWhitespaceFromHeaderValues) {
|
||||
"Connection: close\r\n"
|
||||
"\r\n";
|
||||
|
||||
ASSERT_TRUE(send_request(5, req));
|
||||
EXPECT_EQ(header_value, "\v bar \x1B");
|
||||
std::string res;
|
||||
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.
|
||||
@ -5095,6 +5097,14 @@ TEST(ServerRequestParsingTest, InvalidFieldValueContains_CR_LF_NUL) {
|
||||
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) {
|
||||
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_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\ntoken"));
|
||||
EXPECT_FALSE(detail::fields::is_field_value(std::string("\0", 1)));
|
||||
|
Loading…
x
Reference in New Issue
Block a user