Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove is ipv4/ipv6 functions utils from sdkutils to c-common #39

Merged
merged 2 commits into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading