AK: Validate compressed tags in IPv4-mapped IPv6 address

This disallows parsing IPv4 mapped IPv6 address strings with multiple
compression prefixes.  Tests are provided for the updated
functionality.
This commit is contained in:
Grant Knowlton 2025-07-11 16:11:07 -04:00 committed by Jelle Raaijmakers
parent cf355d48b1
commit 9e1e4f3b15
2 changed files with 31 additions and 3 deletions

View File

@ -144,14 +144,35 @@ public:
auto separator_value = AK::parse_hexadecimal_number<u32>(separator_part);
if (!separator_value.has_value() || separator_value.value() != 0xffff)
return false;
// TODO: this allows multiple compression tags "::" in the prefix, which is technically not legal
for (size_t i = 0; i < parts.size() - 2; i++) {
bool found_compressed = false;
for (size_t i = 0; i < parts.size() - 2;) {
auto part = parts[i].trim_whitespace();
if (part.is_empty())
if (part.is_empty()) {
if (found_compressed)
return false;
bool is_leading = (i == 0);
int empty_parts = 1;
for (size_t j = i + 1; j < parts.size() - 2; j++) {
if (!parts[j].trim_whitespace().is_empty())
break;
empty_parts++;
}
if (is_leading) {
if (empty_parts != 2)
return false;
} else if (empty_parts != 1) {
return false;
}
found_compressed = true;
i += empty_parts;
continue;
}
auto value = AK::parse_hexadecimal_number<u32>(part);
if (!value.has_value() || value.value() != 0)
return false;
i++;
}
return true;
};

View File

@ -103,7 +103,14 @@ TEST_CASE(ipv4_mapped_ipv6)
EXPECT_EQ(ipv4_address_to_map, mapped_address.ipv4_mapped_address().value());
EXPECT_EQ("::ffff:192.168.0.1"sv, MUST(mapped_address.to_string()));
EXPECT_EQ(IPv4Address(192, 168, 1, 9), IPv6Address::from_string("::FFFF:192.168.1.9"sv).value().ipv4_mapped_address().value());
EXPECT_EQ(IPv4Address(192, 168, 1, 7), IPv6Address::from_string("::0:0:ffff:192.168.1.7"sv).value().ipv4_mapped_address().value());
EXPECT_EQ(IPv4Address(192, 168, 2, 5), IPv6Address::from_string("0:0:0::ffff:192.168.2.5"sv).value().ipv4_mapped_address().value());
EXPECT(!IPv6Address::from_string("::abcd:192.168.1.9"sv).has_value());
EXPECT(!IPv6Address::from_string("::::ffff:192.168.1.9"sv).has_value());
EXPECT(!IPv6Address::from_string("ffff::ffff:192.168.1.9"sv).has_value());
EXPECT(!IPv6Address::from_string("0::0::ffff:192.168.1.9"sv).has_value());
EXPECT(!IPv6Address::from_string("::0::ffff:192.168.1.9"sv).has_value());
EXPECT(!IPv6Address::from_string(":0:ffff:192.168.1.9"sv).has_value());
}
TEST_CASE(should_make_empty_optional_from_bad_string)