Skip to content

Commit

Permalink
Remove is ipv4/ipv6 functions utils from sdkutils to c-common (#39)
Browse files Browse the repository at this point in the history
  • Loading branch information
waahm7 authored Apr 22, 2024
1 parent 638fdd6 commit 8c7af71
Show file tree
Hide file tree
Showing 5 changed files with 3 additions and 194 deletions.
11 changes: 0 additions & 11 deletions include/aws/sdkutils/private/endpoints_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,6 @@ AWS_SDKUTILS_API struct aws_owning_cursor aws_endpoints_non_owning_cursor_create
/* Cleans up memory associated with the cursor */
AWS_SDKUTILS_API void aws_owning_cursor_clean_up(struct aws_owning_cursor *cursor);

/*
* Determine whether host cursor is IPv4 string.
*/
AWS_SDKUTILS_API bool aws_is_ipv4(struct aws_byte_cursor host);

/*
* Determine whether host cursor is IPv6 string.
* Supports checking for uri encoded strings and scoped literals.
*/
AWS_SDKUTILS_API bool aws_is_ipv6(struct aws_byte_cursor host, bool is_uri_encoded);

/*
* Determine whether label is a valid host label.
*/
Expand Down
5 changes: 3 additions & 2 deletions source/endpoints_standard_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* SPDX-License-Identifier: Apache-2.0.
*/

#include <aws/common/host_utils.h>
#include <aws/common/json.h>
#include <aws/common/string.h>
#include <aws/common/uri.h>
Expand Down Expand Up @@ -261,7 +262,7 @@ static int s_resolve_fn_uri_encode(
}

static bool s_is_uri_ip(struct aws_byte_cursor host, bool is_uri_encoded) {
return aws_is_ipv4(host) || aws_is_ipv6(host, is_uri_encoded);
return aws_host_utils_is_ipv4(host) || aws_host_utils_is_ipv6(host, is_uri_encoded);
}

static int s_resolve_fn_parse_url(
Expand Down Expand Up @@ -612,7 +613,7 @@ static int s_resolve_is_virtual_hostable_s3_bucket(
out_value->type = AWS_ENDPOINTS_VALUE_BOOLEAN;
out_value->v.boolean = (label_cur.len >= 3 && label_cur.len <= 63) && !has_uppercase_chars &&
aws_is_valid_host_label(label_cur, argv_allow_subdomains.v.boolean) &&
!aws_is_ipv4(label_cur);
!aws_host_utils_is_ipv4(label_cur);

on_done:
aws_endpoints_value_clean_up(&argv_value);
Expand Down
120 changes: 0 additions & 120 deletions source/endpoints_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,129 +11,9 @@

#include <inttypes.h>

#ifdef _MSC_VER /* Disable sscanf warnings on windows. */
# pragma warning(disable : 4204)
# pragma warning(disable : 4706)
# pragma warning(disable : 4996)
#endif

/* 4 octets of 3 chars max + 3 separators + null terminator */
#define AWS_IPV4_STR_LEN 16
#define IP_CHAR_FMT "%03" SCNu16

/* arbitrary max length of a region. curent longest region name is 16 chars */
#define AWS_REGION_LEN 50

bool aws_is_ipv4(struct aws_byte_cursor host) {
if (host.len > AWS_IPV4_STR_LEN - 1) {
return false;
}

char copy[AWS_IPV4_STR_LEN] = {0};
memcpy(copy, host.ptr, host.len);

uint16_t octet[4] = {0};
char remainder[2] = {0};
if (4 != sscanf(
copy,
IP_CHAR_FMT "." IP_CHAR_FMT "." IP_CHAR_FMT "." IP_CHAR_FMT "%1s",
&octet[0],
&octet[1],
&octet[2],
&octet[3],
remainder)) {
return false;
}

for (size_t i = 0; i < 4; ++i) {
if (octet[i] > 255) {
return false;
}
}

return true;
}

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

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

static bool s_is_ipv6_char(uint8_t value) {
return aws_isxdigit(value) || value == ':';
}

/* actual encoding is %25, but % is omitted for simplicity, since split removes it */
static struct aws_byte_cursor s_percent_uri_enc = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("25");
/*
* IPv6 format:
* 8 groups of 4 hex chars separated by colons (:)
* leading 0s in each group can be skipped
* 2 or more consecutive zero groups can be replaced by double colon (::),
* but only once.
* ipv6 literal can be scoped by to zone by appending % followed by zone name
* ( does not look like there is length reqs on zone name length. this
* implementation enforces that its > 1 )
* ipv6 can be embedded in url, in which case it must be wrapped inside []
* and % be uri encoded as %25.
* Implementation is fairly trivial and just iterates through the string
* keeping track of the spec above.
*/
bool aws_is_ipv6(struct aws_byte_cursor host, bool is_uri_encoded) {
if (host.len == 0) {
return false;
}

if (is_uri_encoded) {
if (!s_starts_with(host, '[') || !s_ends_with(host, ']')) {
return false;
}
aws_byte_cursor_advance(&host, 1);
--host.len;
}

struct aws_byte_cursor substr = {0};
/* first split is required ipv6 part */
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_starts_with(substr, ':') || s_ends_with(substr, ':')) ||
!aws_byte_cursor_satisfies_pred(&substr, s_is_ipv6_char)) {
return false;
}

uint8_t group_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)) { /* only one double colon allowed */
return false;
}

has_double_colon = has_double_colon || group.len == 0;
}

/* second split is optional zone part */
if (aws_byte_cursor_next_split(&host, '%', &substr)) {
if ((is_uri_encoded &&
(substr.len < 3 ||
!aws_byte_cursor_starts_with(&substr, &s_percent_uri_enc))) || /* encoding for % + 1 extra char */
(!is_uri_encoded && substr.len == 0) || /* at least 1 char */
!aws_byte_cursor_satisfies_pred(&substr, aws_isalnum)) {
return false;
}
}

return has_double_colon ? group_count < 7 : group_count == 8;
}

bool aws_is_valid_host_label(struct aws_byte_cursor label, bool allow_subdomains) {
bool next_must_be_alnum = true;
size_t subdomain_count = 0;
Expand Down
2 changes: 0 additions & 2 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,6 @@ add_test_case(test_endpoints_valid_hostlabel)
add_test_case(test_endpoints_condition_mem_clean_up)
add_test_case(test_endpoints_custom)

add_test_case(endpoints_eval_util_is_ipv4)
add_test_case(endpoints_eval_util_is_ipv6)
add_test_case(endpoints_uri_normalize_path)
add_test_case(endpoints_byte_buf_init_from_resolved_templated_string)

Expand Down
59 changes: 0 additions & 59 deletions tests/endpoints_util_tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,65 +8,6 @@
#include <aws/sdkutils/private/endpoints_util.h>
#include <aws/testing/aws_test_harness.h>

AWS_TEST_CASE(endpoints_eval_util_is_ipv4, s_test_is_ipv4)
static int s_test_is_ipv4(struct aws_allocator *allocator, void *ctx) {
(void)allocator;
(void)ctx;

ASSERT_TRUE(aws_is_ipv4(aws_byte_cursor_from_c_str("0.0.0.0")));
ASSERT_TRUE(aws_is_ipv4(aws_byte_cursor_from_c_str("127.0.0.1")));
ASSERT_TRUE(aws_is_ipv4(aws_byte_cursor_from_c_str("255.255.255.255")));
ASSERT_TRUE(aws_is_ipv4(aws_byte_cursor_from_c_str("192.168.1.1")));

ASSERT_FALSE(aws_is_ipv4(aws_byte_cursor_from_c_str("256.0.0.1")));
ASSERT_FALSE(aws_is_ipv4(aws_byte_cursor_from_c_str("127.0.0")));
ASSERT_FALSE(aws_is_ipv4(aws_byte_cursor_from_c_str("127.0")));
ASSERT_FALSE(aws_is_ipv4(aws_byte_cursor_from_c_str("127")));
ASSERT_FALSE(aws_is_ipv4(aws_byte_cursor_from_c_str("")));

ASSERT_FALSE(aws_is_ipv4(aws_byte_cursor_from_c_str("foo.com")));
ASSERT_FALSE(aws_is_ipv4(aws_byte_cursor_from_c_str("a.b.c.d")));
ASSERT_FALSE(aws_is_ipv4(aws_byte_cursor_from_c_str("a127.0.0.1")));
ASSERT_FALSE(aws_is_ipv4(aws_byte_cursor_from_c_str("127.0.0.1a")));
ASSERT_FALSE(aws_is_ipv4(aws_byte_cursor_from_c_str("127.0.0.1011")));

return AWS_OP_SUCCESS;
}

AWS_TEST_CASE(endpoints_eval_util_is_ipv6, s_test_is_ipv6)
static int s_test_is_ipv6(struct aws_allocator *allocator, void *ctx) {
(void)allocator;
(void)ctx;

ASSERT_TRUE(aws_is_ipv6(aws_byte_cursor_from_c_str("0:0:0000:0000:0000:0:0:0"), false));
ASSERT_TRUE(aws_is_ipv6(aws_byte_cursor_from_c_str("2001:0db8:0000:0000:0000:8a2e:0370:7334"), false));
ASSERT_TRUE(aws_is_ipv6(aws_byte_cursor_from_c_str("2001:0DB8:0000:0000:0000:8a2e:0370:7334"), false));
ASSERT_TRUE(aws_is_ipv6(aws_byte_cursor_from_c_str("fe80::1"), false));
ASSERT_TRUE(aws_is_ipv6(aws_byte_cursor_from_c_str("fe80::1%en0"), false));
ASSERT_TRUE(aws_is_ipv6(aws_byte_cursor_from_c_str("[2001:0db8:0000:0000:0000:8a2e:0370:7334]"), true));
ASSERT_TRUE(aws_is_ipv6(aws_byte_cursor_from_c_str("[fe80::1]"), true));
ASSERT_TRUE(aws_is_ipv6(aws_byte_cursor_from_c_str("[fe80::1%25en0]"), true));
ASSERT_TRUE(aws_is_ipv6(aws_byte_cursor_from_c_str("[2001:db8:85a3:8d3:1319:8a2e:370:7348]"), true));

ASSERT_FALSE(aws_is_ipv6(aws_byte_cursor_from_c_str("2001:0db8:0000:0000:0000:8a2e:0370"), false));
ASSERT_FALSE(aws_is_ipv6(aws_byte_cursor_from_c_str("2001:0db8:0000:0000:0000:8a2e:0370:"), false));
ASSERT_FALSE(aws_is_ipv6(aws_byte_cursor_from_c_str("2001::"), false));
ASSERT_FALSE(aws_is_ipv6(aws_byte_cursor_from_c_str("2001:0db8:0000:0000:0000:8a2e:0370:7334:8745"), false));
ASSERT_FALSE(aws_is_ipv6(aws_byte_cursor_from_c_str(":2001:0db8:0000:0000:0000:8a2e:0370:7334:8745"), false));
ASSERT_FALSE(aws_is_ipv6(aws_byte_cursor_from_c_str("z001:0db8:0000:0000:0000:8a2e:0370:7334:8745"), false));
ASSERT_FALSE(aws_is_ipv6(aws_byte_cursor_from_c_str("z001::8a2e::8745"), false));
ASSERT_FALSE(aws_is_ipv6(aws_byte_cursor_from_c_str("::2001:0db8:0000:0000:8a2e:0370:7334"), false));

ASSERT_FALSE(aws_is_ipv6(aws_byte_cursor_from_c_str("fe80::1%25en0"), true));
ASSERT_FALSE(aws_is_ipv6(aws_byte_cursor_from_c_str("[fe80::1%en0]"), true));
ASSERT_FALSE(aws_is_ipv6(aws_byte_cursor_from_c_str("[fe80::1%24en0]"), true));
ASSERT_FALSE(aws_is_ipv6(aws_byte_cursor_from_c_str("[fe80::1%25en0"), true));
ASSERT_FALSE(aws_is_ipv6(aws_byte_cursor_from_c_str("fe80::1%25en0]"), true));
ASSERT_FALSE(aws_is_ipv6(aws_byte_cursor_from_c_str("[fe80::1%25]"), true));

return AWS_OP_SUCCESS;
}

AWS_TEST_CASE(endpoints_uri_normalize_path, s_test_uri_normalize_path)
static int s_test_uri_normalize_path(struct aws_allocator *allocator, void *ctx) {
(void)ctx;
Expand Down

0 comments on commit 8c7af71

Please sign in to comment.