mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2026-10-23 11:54:42 +00:00
Reject trailing characters in URL port numbers (#2593)
parse_port checked only the error code of from_chars, which stops at the first non-digit, so http://host:80abc was accepted as port 80, and a redirect Location with such a port was followed. RFC 3986 defines port as *DIGIT. Require the whole string to be consumed, as #2590 does for quality values.
This commit is contained in:
2 files changed
+36
-1
No files matched your search
@@ -834,7 +834,9 @@ inline from_chars_result<double> from_chars(const char *first, const char *last,
|
|||||||
inline bool parse_port(const char *s, size_t len, int &port) {
|
inline bool parse_port(const char *s, size_t len, int &port) {
|
||||||
int val = 0;
|
int val = 0;
|
||||||
auto r = from_chars(s, s + len, val);
|
auto r = from_chars(s, s + len, val);
|
||||||
if (r.ec != std::errc{} || val < 1 || val > 65535) { return false; }
|
if (r.ec != std::errc{} || r.ptr != s + len || val < 1 || val > 65535) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
port = val;
|
port = val;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3754,6 +3754,34 @@ TEST(RedirectToDifferentPort, OverflowPortNumber) {
|
|||||||
EXPECT_FALSE(res);
|
EXPECT_FALSE(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(RedirectToDifferentPort, TrailingCharactersInPort) {
|
||||||
|
Server svr;
|
||||||
|
auto port = svr.bind_to_any_port(HOST);
|
||||||
|
svr.Get("/redir", [&](const Request & /*req*/, Response &res) {
|
||||||
|
// The server's own port followed by junk must not be followed
|
||||||
|
res.set_redirect("http://" + std::string(HOST) + ":" +
|
||||||
|
std::to_string(port) + "junk/target");
|
||||||
|
});
|
||||||
|
svr.Get("/target", [&](const Request & /*req*/, Response &res) {
|
||||||
|
res.set_content("target", "text/plain");
|
||||||
|
});
|
||||||
|
|
||||||
|
auto thread = std::thread([&]() { svr.listen_after_bind(); });
|
||||||
|
auto se = detail::scope_exit([&] {
|
||||||
|
svr.stop();
|
||||||
|
thread.join();
|
||||||
|
ASSERT_FALSE(svr.is_running());
|
||||||
|
});
|
||||||
|
|
||||||
|
svr.wait_until_ready();
|
||||||
|
|
||||||
|
Client cli(HOST, port);
|
||||||
|
cli.set_follow_location(true);
|
||||||
|
|
||||||
|
auto res = cli.Get("/redir");
|
||||||
|
EXPECT_FALSE(res);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(RedirectFromPageWithContent, Redirect) {
|
TEST(RedirectFromPageWithContent, Redirect) {
|
||||||
Server svr;
|
Server svr;
|
||||||
|
|
||||||
@@ -13848,6 +13876,11 @@ TEST(HostAndPortPropertiesTest, PortOutOfRange) {
|
|||||||
ASSERT_FALSE(cli.is_valid());
|
ASSERT_FALSE(cli.is_valid());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(HostAndPortPropertiesTest, TrailingCharactersInPort) {
|
||||||
|
httplib::Client cli("http://www.google.com:80abc");
|
||||||
|
ASSERT_FALSE(cli.is_valid());
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CPPHTTPLIB_SSL_ENABLED
|
#ifdef CPPHTTPLIB_SSL_ENABLED
|
||||||
TEST(HostAndPortPropertiesTest, SSL) {
|
TEST(HostAndPortPropertiesTest, SSL) {
|
||||||
httplib::SSLClient cli("www.google.com");
|
httplib::SSLClient cli("www.google.com");
|
||||||
|
|||||||
Reference in new issue
Block a user