Skip to content

Commit

Permalink
fix bug in resolving templates if strings contain escaped quotes (#16)
Browse files Browse the repository at this point in the history
* fix bug in resolving templates if strings contain escaped quotes
  • Loading branch information
DmitriyMusatkin committed Oct 27, 2022
1 parent 3b2cbbb commit 662905e
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 15 deletions.
10 changes: 5 additions & 5 deletions include/aws/sdkutils/private/endpoints_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,20 @@ struct aws_owning_cursor {
};

/* Clones string and wraps it in owning cursor. */
struct aws_owning_cursor aws_endpoints_owning_cursor_create(
AWS_SDKUTILS_API struct aws_owning_cursor aws_endpoints_owning_cursor_create(
struct aws_allocator *allocator,
const struct aws_string *str);
/* Creates new cursor that takes ownership of created string. */
struct aws_owning_cursor aws_endpoints_owning_cursor_from_string(struct aws_string *str);
AWS_SDKUTILS_API struct aws_owning_cursor aws_endpoints_owning_cursor_from_string(struct aws_string *str);
/* Clones memory pointer to by cursor and wraps in owning cursor */
struct aws_owning_cursor aws_endpoints_owning_cursor_from_cursor(
AWS_SDKUTILS_API struct aws_owning_cursor aws_endpoints_owning_cursor_from_cursor(
struct aws_allocator *allocator,
const struct aws_byte_cursor cur);
/* Creates owning cursor with memory pointer set to NULL */
struct aws_owning_cursor aws_endpoints_non_owning_cursor_create(struct aws_byte_cursor cur);
AWS_SDKUTILS_API struct aws_owning_cursor aws_endpoints_non_owning_cursor_create(struct aws_byte_cursor cur);

/* Cleans up memory associated with the cursor */
void aws_owning_cursor_clean_up(struct aws_owning_cursor *cursor);
AWS_SDKUTILS_API void aws_owning_cursor_clean_up(struct aws_owning_cursor *cursor);

/*
* Determine whether host cursor is IPv4 string.
Expand Down
30 changes: 20 additions & 10 deletions source/endpoints_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -333,10 +333,18 @@ static bool s_split_on_first_delim(
static int s_buf_append_and_update_quote_count(
struct aws_byte_buf *buf,
struct aws_byte_cursor to_append,
size_t *quote_count) {
for (size_t idx = 0; idx < to_append.len; ++idx) {
if (to_append.ptr[idx] == '"' && !(idx > 0 && to_append.ptr[idx - 1] == '\\')) {
++*quote_count;
size_t *quote_count,
bool is_json) {

/* Dont count quotes if its not json. escaped quotes will be replaced with
regular quotes when ruleset json is parsed, which will lead to incorrect
results for when templates should be resolved in regular strings.
Note: in json blobs escaped quotes are preserved and bellow approach works. */
if (is_json) {
for (size_t idx = 0; idx < to_append.len; ++idx) {
if (to_append.ptr[idx] == '"' && !(idx > 0 && to_append.ptr[idx - 1] == '\\')) {
++*quote_count;
}
}
}
return aws_byte_buf_append_dynamic(buf, &to_append);
Expand All @@ -354,12 +362,14 @@ static struct aws_byte_cursor escaped_opening_curly = AWS_BYTE_CUR_INIT_FROM_STR
int s_append_template_prefix_to_buffer(
struct aws_byte_buf *out_buf,
struct aws_byte_cursor prefix,
size_t *quote_count) {
size_t *quote_count,
bool is_json) {

struct aws_byte_cursor split = {0};
struct aws_byte_cursor rest = {0};

while (s_split_on_first_delim(prefix, '}', &split, &rest)) {
if (s_buf_append_and_update_quote_count(out_buf, split, quote_count)) {
if (s_buf_append_and_update_quote_count(out_buf, split, quote_count, is_json)) {
AWS_LOGF_ERROR(AWS_LS_SDKUTILS_ENDPOINTS_GENERAL, "Failed to append to resolved template buffer.");
goto on_error;
}
Expand Down Expand Up @@ -388,7 +398,7 @@ int s_append_template_prefix_to_buffer(
prefix = rest;
}

if (s_buf_append_and_update_quote_count(out_buf, split, quote_count)) {
if (s_buf_append_and_update_quote_count(out_buf, split, quote_count, is_json)) {
AWS_LOGF_ERROR(AWS_LS_SDKUTILS_ENDPOINTS_GENERAL, "Failed to append to resolved template buffer.");
goto on_error;
}
Expand Down Expand Up @@ -419,7 +429,7 @@ int aws_byte_buf_init_from_resolved_templated_string(
struct aws_byte_cursor split = {0};
struct aws_byte_cursor rest = {0};
while (s_split_on_first_delim(string, '{', &split, &rest)) {
if (s_append_template_prefix_to_buffer(out_buf, split, &quote_count)) {
if (s_append_template_prefix_to_buffer(out_buf, split, &quote_count, is_json)) {
AWS_LOGF_ERROR(
AWS_LS_SDKUTILS_ENDPOINTS_GENERAL, "Failed to append to buffer while evaluating templated sting.");
goto on_error;
Expand Down Expand Up @@ -460,15 +470,15 @@ int aws_byte_buf_init_from_resolved_templated_string(
goto on_error;
}

if (s_buf_append_and_update_quote_count(out_buf, resolved_template.cur, &quote_count)) {
if (s_buf_append_and_update_quote_count(out_buf, resolved_template.cur, &quote_count, is_json)) {
AWS_LOGF_ERROR(AWS_LS_SDKUTILS_ENDPOINTS_GENERAL, "Failed to append resolved value.");
goto on_error;
}

aws_owning_cursor_clean_up(&resolved_template);
}

if (s_buf_append_and_update_quote_count(out_buf, split, &quote_count)) {
if (s_buf_append_and_update_quote_count(out_buf, split, &quote_count, is_json)) {
AWS_LOGF_ERROR(AWS_LS_SDKUTILS_ENDPOINTS_GENERAL, "Failed to append to resolved template buffer.");
goto on_error;
}
Expand Down
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ add_test_case(endpoints_eval_util_is_ipv4)
add_test_case(endpoints_eval_util_is_ipv6)
add_test_case(endpoints_map_region_to_partition)
add_test_case(endpoints_uri_normalize_path)
add_test_case(endpoints_byte_buf_init_from_resolved_templated_string)

set(TEST_BINARY_NAME ${PROJECT_NAME}-tests)
generate_test_driver(${TEST_BINARY_NAME})
Expand Down
43 changes: 43 additions & 0 deletions tests/endpoints_util_tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,46 @@ static int s_test_uri_normalize_path(struct aws_allocator *allocator, void *ctx)

return AWS_OP_SUCCESS;
}

int s_resolve_cb(struct aws_byte_cursor template, void *user_data, struct aws_owning_cursor *out_resolved) {
(void)template;
(void)user_data;
*out_resolved = aws_endpoints_non_owning_cursor_create(aws_byte_cursor_from_c_str("test"));
return AWS_OP_SUCCESS;
}

AWS_TEST_CASE(
endpoints_byte_buf_init_from_resolved_templated_string,
s_test_byte_buf_init_from_resolved_templated_string)
static int s_test_byte_buf_init_from_resolved_templated_string(struct aws_allocator *allocator, void *ctx) {
(void)ctx;

struct aws_byte_buf buf;

ASSERT_SUCCESS(aws_byte_buf_init_from_resolved_templated_string(
allocator, &buf, aws_byte_cursor_from_c_str("{e} a {b}{c} a {d}"), s_resolve_cb, NULL, false));
ASSERT_CURSOR_VALUE_CSTRING_EQUALS(aws_byte_cursor_from_buf(&buf), "test a testtest a test");
aws_byte_buf_clean_up(&buf);

ASSERT_SUCCESS(aws_byte_buf_init_from_resolved_templated_string(
allocator,
&buf,
aws_byte_cursor_from_c_str("{ \"a\": \"{b} {d} \", \"c\": \" {e} \"}"),
s_resolve_cb,
NULL,
true));
ASSERT_CURSOR_VALUE_CSTRING_EQUALS(aws_byte_cursor_from_buf(&buf), "{ \"a\": \"test test \", \"c\": \" test \"}");
aws_byte_buf_clean_up(&buf);

ASSERT_SUCCESS(aws_byte_buf_init_from_resolved_templated_string(
allocator, &buf, aws_byte_cursor_from_c_str("a \" {b} \" a"), s_resolve_cb, NULL, false));
ASSERT_CURSOR_VALUE_CSTRING_EQUALS(aws_byte_cursor_from_buf(&buf), "a \" test \" a");
aws_byte_buf_clean_up(&buf);

ASSERT_SUCCESS(aws_byte_buf_init_from_resolved_templated_string(
allocator, &buf, aws_byte_cursor_from_c_str("{ \"a\": \"a \\\" {b} \\\" a\" }"), s_resolve_cb, NULL, true));
ASSERT_CURSOR_VALUE_CSTRING_EQUALS(aws_byte_cursor_from_buf(&buf), "{ \"a\": \"a \\\" test \\\" a\" }");
aws_byte_buf_clean_up(&buf);

return AWS_OP_SUCCESS;
}

0 comments on commit 662905e

Please sign in to comment.