mirror of
https://github.com/transmission/transmission
synced 2025-01-30 10:52:00 +00:00
fix: parsing of ipv6 tracker announce URLs (#5174)
This commit is contained in:
parent
39e3e1d87b
commit
033d698306
2 changed files with 52 additions and 3 deletions
|
@ -292,7 +292,6 @@ std::string_view getSiteName(std::string_view host)
|
|||
|
||||
return host;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
std::optional<tr_url_parsed_t> tr_urlParse(std::string_view url)
|
||||
|
@ -335,8 +334,31 @@ std::optional<tr_url_parsed_t> tr_urlParse(std::string_view url)
|
|||
parsed.authority = url.substr(0, pos);
|
||||
url = pos == std::string_view::npos ? ""sv : url.substr(pos);
|
||||
|
||||
// A host identified by an Internet Protocol literal address, version 6
|
||||
// [RFC3513] or later, is distinguished by enclosing the IP literal
|
||||
// within square brackets ("[" and "]"). This is the only place where
|
||||
// square bracket characters are allowed in the URI syntax.
|
||||
auto remain = parsed.authority;
|
||||
parsed.host = tr_strvSep(&remain, ':');
|
||||
if (tr_strvStartsWith(remain, '['))
|
||||
{
|
||||
remain.remove_prefix(1); // '['
|
||||
parsed.host = tr_strvSep(&remain, ']');
|
||||
if (tr_strvStartsWith(remain, ':'))
|
||||
{
|
||||
remain.remove_prefix(1);
|
||||
}
|
||||
}
|
||||
// Not legal by RFC3986 standards, but sometimes users omit
|
||||
// square brackets for an IPv6 address with an implicit port
|
||||
else if (std::count(std::begin(remain), std::end(remain), ':') > 1U)
|
||||
{
|
||||
parsed.host = remain;
|
||||
remain = ""sv;
|
||||
}
|
||||
else
|
||||
{
|
||||
parsed.host = tr_strvSep(&remain, ':');
|
||||
}
|
||||
parsed.sitename = getSiteName(parsed.host);
|
||||
parsed.port = parsePort(!std::empty(remain) ? remain : getPortForScheme(parsed.scheme));
|
||||
}
|
||||
|
|
|
@ -111,7 +111,7 @@ TEST_F(WebUtilsTest, urlParse)
|
|||
EXPECT_EQ("/some/other/path"sv, parsed->path);
|
||||
EXPECT_EQ(80, parsed->port);
|
||||
|
||||
// test a host with an IP address
|
||||
// test a host with an IPv4 address
|
||||
url = "https://127.0.0.1:8080/some/path"sv;
|
||||
parsed = tr_urlParse(url);
|
||||
EXPECT_TRUE(parsed);
|
||||
|
@ -120,6 +120,33 @@ TEST_F(WebUtilsTest, urlParse)
|
|||
EXPECT_EQ("127.0.0.1"sv, parsed->host);
|
||||
EXPECT_EQ("/some/path"sv, parsed->path);
|
||||
EXPECT_EQ(8080, parsed->port);
|
||||
|
||||
// test a host with a bracketed IPv6 address and explicit port
|
||||
url = "http://[2001:0db8:11a3:09d7:1f34:8a2e:07a0:765d]:8080/announce"sv;
|
||||
parsed = tr_urlParse(url);
|
||||
EXPECT_EQ("http"sv, parsed->scheme);
|
||||
EXPECT_EQ("2001:0db8:11a3:09d7:1f34:8a2e:07a0:765d"sv, parsed->sitename);
|
||||
EXPECT_EQ("2001:0db8:11a3:09d7:1f34:8a2e:07a0:765d"sv, parsed->host);
|
||||
EXPECT_EQ("/announce"sv, parsed->path);
|
||||
EXPECT_EQ(8080, parsed->port);
|
||||
|
||||
// test a host with a bracketed IPv6 address and implicit port
|
||||
url = "http://[2001:0db8:11a3:09d7:1f34:8a2e:07a0:765d]/announce"sv;
|
||||
parsed = tr_urlParse(url);
|
||||
EXPECT_EQ("http"sv, parsed->scheme);
|
||||
EXPECT_EQ("2001:0db8:11a3:09d7:1f34:8a2e:07a0:765d"sv, parsed->sitename);
|
||||
EXPECT_EQ("2001:0db8:11a3:09d7:1f34:8a2e:07a0:765d"sv, parsed->host);
|
||||
EXPECT_EQ("/announce"sv, parsed->path);
|
||||
EXPECT_EQ(80, parsed->port);
|
||||
|
||||
// test a host with an unbracketed IPv6 address and implicit port
|
||||
url = "http://2001:0db8:11a3:09d7:1f34:8a2e:07a0:765d/announce"sv;
|
||||
parsed = tr_urlParse(url);
|
||||
EXPECT_EQ("http"sv, parsed->scheme);
|
||||
EXPECT_EQ("2001:0db8:11a3:09d7:1f34:8a2e:07a0:765d"sv, parsed->sitename);
|
||||
EXPECT_EQ("2001:0db8:11a3:09d7:1f34:8a2e:07a0:765d"sv, parsed->host);
|
||||
EXPECT_EQ("/announce"sv, parsed->path);
|
||||
EXPECT_EQ(80, parsed->port);
|
||||
}
|
||||
|
||||
TEST(WebUtilsTest, urlParseFuzz)
|
||||
|
|
Loading…
Reference in a new issue