Skip to content

Commit

Permalink
fixup is ipv6 logic
Browse files Browse the repository at this point in the history
  • Loading branch information
DmitriyMusatkin committed Jan 17, 2025
1 parent c5a0812 commit 006d3b3
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 16 deletions.
42 changes: 27 additions & 15 deletions source/host_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <aws/common/host_utils.h>
#include <aws/common/string.h>
#include <inttypes.h>
#include <aws/common/logging.h>

#ifdef _MSC_VER /* Disable sscanf warnings on windows. */
# pragma warning(disable : 4204)
Expand All @@ -20,10 +21,6 @@ static bool s_is_ipv6_char(uint8_t value) {
return aws_isxdigit(value) || value == ':';
}

static bool s_ends_with(struct aws_byte_cursor cur, uint8_t ch) {
return cur.len > 0 && cur.ptr[cur.len - 1] == ch;
}

bool aws_host_utils_is_ipv4(struct aws_byte_cursor host) {
if (host.len > AWS_IPV4_STR_LEN - 1) {
return false;
Expand Down Expand Up @@ -79,24 +76,39 @@ bool aws_host_utils_is_ipv6(struct aws_byte_cursor host, bool is_uri_encoded) {
bool is_split = aws_byte_cursor_next_split(&host, '%', &substr);
AWS_ASSERT(is_split); /* function is guaranteed to return at least one split */

if (!is_split || substr.len == 0 || s_ends_with(substr, ':') ||
if (!is_split || substr.len < 2 || substr.len > 39 ||
!aws_byte_cursor_satisfies_pred(&substr, s_is_ipv6_char)) {
return false;
}

uint8_t group_count = 0;
if ((substr.ptr[0] == ':' && substr.ptr[1] != ':') || /* no single colon at start */
(substr.ptr[substr.len - 1] == ':' && substr.ptr[substr.len - 2] != ':')) { /* no single colon at end */
return false;
}

uint8_t group_count = 1; /* string itself is the first group and then every new : we encounter is new group */
uint8_t digit_count = 0;
bool has_double_colon = false;
struct aws_byte_cursor group = {0};
while (aws_byte_cursor_next_split(&substr, ':', &group)) {
++group_count;

if (group_count > 8 || /* too many groups */
group.len > 4 || /* too many chars in group */
(has_double_colon && group.len == 0 && group_count > 2)) { /* only one double colon allowed */
return false;
for (size_t i = 0; i < substr.len; ++i) {
if (substr.ptr[i] == ':') {
++group_count;
digit_count = 0;

if (i > 0 && substr.ptr[i - 1] == ':') {
if (has_double_colon) { /* one double colon max */
return false;
}
has_double_colon = true;
}
} else {
++digit_count;
}

has_double_colon = has_double_colon || group.len == 0;
if (digit_count > 4 || /* too many digits in group */
group_count > 8 ) { /* too many groups */
return false;
}
}

/* second split is optional zone part */
Expand All @@ -110,5 +122,5 @@ bool aws_host_utils_is_ipv6(struct aws_byte_cursor host, bool is_uri_encoded) {
}
}

return has_double_colon ? group_count < 7 : group_count == 8;
return has_double_colon ? group_count <= 7 : group_count == 8;
}
20 changes: 19 additions & 1 deletion tests/host_util_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,20 @@ static int s_test_is_ipv6(struct aws_allocator *allocator, void *ctx) {
ASSERT_TRUE(aws_host_utils_is_ipv6(aws_byte_cursor_from_c_str("fe80::1"), true));
ASSERT_TRUE(aws_host_utils_is_ipv6(aws_byte_cursor_from_c_str("fe80::1%25en0"), true));
ASSERT_TRUE(aws_host_utils_is_ipv6(aws_byte_cursor_from_c_str("2001:db8:85a3:8d3:1319:8a2e:370:7348"), true));
ASSERT_TRUE(aws_host_utils_is_ipv6(aws_byte_cursor_from_c_str("2001::"), false));

ASSERT_TRUE(aws_host_utils_is_ipv6(aws_byte_cursor_from_c_str("2001:DB8:85A3::8A2E:370:7334"), false));
ASSERT_TRUE(aws_host_utils_is_ipv6(aws_byte_cursor_from_c_str("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), false));
ASSERT_TRUE(aws_host_utils_is_ipv6(aws_byte_cursor_from_c_str("2001:DB8:85A3::8A2E:370:7334"), false));
ASSERT_TRUE(aws_host_utils_is_ipv6(aws_byte_cursor_from_c_str("::ffff"), false));
ASSERT_TRUE(aws_host_utils_is_ipv6(aws_byte_cursor_from_c_str("::"), false));
ASSERT_TRUE(aws_host_utils_is_ipv6(aws_byte_cursor_from_c_str("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), false));
ASSERT_TRUE(aws_host_utils_is_ipv6(aws_byte_cursor_from_c_str("2001:db8:85a3:0:0:8a2e:370:7334"), false));
ASSERT_TRUE(aws_host_utils_is_ipv6(aws_byte_cursor_from_c_str("0:0:0:0:0:0:0:0"), false));
ASSERT_TRUE(aws_host_utils_is_ipv6(aws_byte_cursor_from_c_str("2001:db8::"), false));

ASSERT_FALSE(aws_host_utils_is_ipv6(aws_byte_cursor_from_c_str("2001:0db8:0000:0000:0000:8a2e:0370"), false));
ASSERT_FALSE(aws_host_utils_is_ipv6(aws_byte_cursor_from_c_str("2001:0db8:0000:0000:0000:8a2e:0370:"), false));
ASSERT_FALSE(aws_host_utils_is_ipv6(aws_byte_cursor_from_c_str("2001::"), false));
ASSERT_FALSE(
aws_host_utils_is_ipv6(aws_byte_cursor_from_c_str("2001:0db8:0000:0000:0000:8a2e:0370:7334:8745"), false));
ASSERT_FALSE(
Expand All @@ -69,5 +79,13 @@ static int s_test_is_ipv6(struct aws_allocator *allocator, void *ctx) {
ASSERT_FALSE(aws_host_utils_is_ipv6(aws_byte_cursor_from_c_str("fe80::1%25en0]"), true));
ASSERT_FALSE(aws_host_utils_is_ipv6(aws_byte_cursor_from_c_str("fe80::1%25"), true));

ASSERT_FALSE(aws_host_utils_is_ipv6(aws_byte_cursor_from_c_str("2001:db8:85a3:0000:0000:8a2e:0370:7334:1"), false));
ASSERT_FALSE(aws_host_utils_is_ipv6(aws_byte_cursor_from_c_str("2001:db8:85a3:0000"), false));
ASSERT_FALSE(aws_host_utils_is_ipv6(aws_byte_cursor_from_c_str("2001:0db8:85a3:0000:0000:8a2e:0370:7334:"), false));
ASSERT_FALSE(aws_host_utils_is_ipv6(aws_byte_cursor_from_c_str("g001:0db8:85a3:0000:0000:8a2e:0370:7334"), false));
ASSERT_FALSE(aws_host_utils_is_ipv6(aws_byte_cursor_from_c_str("2001:db8::85a3::1"), false));
ASSERT_FALSE(aws_host_utils_is_ipv6(aws_byte_cursor_from_c_str(":2001:db8:85a3:0000:0000:8a2e:0370:7334"), false));
ASSERT_TRUE(aws_host_utils_is_ipv6(aws_byte_cursor_from_c_str("0:0:0:0:0:0:0:0"), false));

return AWS_OP_SUCCESS;
}

0 comments on commit 006d3b3

Please sign in to comment.