AK+Tests: Add support for URI syntax in IPv6Address::from_string

This supports IPv6 strings that start with `[` and end with `]` in
accordance with RFC3986 which states:

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.
This commit is contained in:
rmg-x 2025-04-05 11:17:13 -05:00
parent 3c64c5f8d1
commit 5436d58037
2 changed files with 23 additions and 0 deletions

View file

@ -111,6 +111,18 @@ public:
if (string.is_null())
return {};
// NOTE: This supports URI syntax (square brackets) for IPv6 addresses.
// See: https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2
auto const starts_with_bracket = string.starts_with('[');
auto const ends_with_bracket = string.ends_with(']');
if (starts_with_bracket || ends_with_bracket) {
if (!starts_with_bracket || !ends_with_bracket)
return {};
string = string.substring_view(1, string.length() - 2);
}
auto const parts = string.split_view(':', SplitBehavior::KeepEmpty);
if (parts.is_empty())
return {};

View file

@ -82,6 +82,17 @@ TEST_CASE(should_make_ipv6_address_from_string)
EXPECT_EQ(IPv6Address::from_string("102:0:506:708:900::"sv).value(), IPv6Address({ 1, 2, 0, 0, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0 }));
EXPECT_EQ(IPv6Address::from_string("::304:506:708:90a:b0c:d0e:f10"sv).value(), IPv6Address({ 0, 0, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }));
EXPECT_EQ(IPv6Address::from_string("102:304::708:90a:b0c:d0e:f10"sv).value(), IPv6Address({ 1, 2, 3, 4, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }));
EXPECT_EQ(IPv6Address::from_string("[102:304::708:90a:b0c:d0e:f10]"sv).value(), IPv6Address({ 1, 2, 3, 4, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }));
EXPECT_EQ(IPv6Address::from_string("[::304:506:708:90a:b0c:d0e:f10]"sv).value(), IPv6Address({ 0, 0, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }));
}
TEST_CASE(should_not_make_ipv6_address_from_string)
{
EXPECT_EQ(IPv6Address::from_string("[102:0:506:708:900::10"sv), OptionalNone {});
EXPECT_EQ(IPv6Address::from_string("102:0:506:708:900::10]"sv), OptionalNone {});
EXPECT_EQ(IPv6Address::from_string("[::304:506:708:90a:b0c:d0e:f10]]"sv), OptionalNone {});
EXPECT_EQ(IPv6Address::from_string("[[::304:506:708:90a:b0c:d0e:f10]"sv), OptionalNone {});
EXPECT_EQ(IPv6Address::from_string("[[::304:506:708:90a:b0c:d0e:f10]]"sv), OptionalNone {});
}
TEST_CASE(ipv4_mapped_ipv6)