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:
KBS
2026-10-02 21:07:34 -04:00
committed by GitHub
parent 43863e1f67
commit 10aadd57f7
2 changed files with 36 additions and 1 deletions
+33
View File
@@ -3754,6 +3754,34 @@ TEST(RedirectToDifferentPort, OverflowPortNumber) {
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) {
Server svr;
@@ -13848,6 +13876,11 @@ TEST(HostAndPortPropertiesTest, PortOutOfRange) {
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
TEST(HostAndPortPropertiesTest, SSL) {
httplib::SSLClient cli("www.google.com");