summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrobot-contrib <[email protected]>2026-07-24 12:05:12 +0300
committerrobot-contrib <[email protected]>2026-07-24 13:01:24 +0300
commit4bb8b0576dfe1cd85fd17afeaef319d73d3f9784 (patch)
tree17e54648bcd3df81bce10b88d6b231bfddcbc638
parent0c4c053d1ed716ef9f95692b6456882e483e4d24 (diff)
Update contrib/restricted/aws/aws-c-common to 0.14.2
commit_hash:eb6d4f4b66b70983cf36d1dac34fe1d90aac5a66
-rw-r--r--contrib/restricted/aws/aws-c-common/.yandex_meta/override.nix4
-rw-r--r--contrib/restricted/aws/aws-c-common/include/aws/common/byte_buf.h35
-rw-r--r--contrib/restricted/aws/aws-c-common/source/byte_buf.c15
-rw-r--r--contrib/restricted/aws/aws-c-common/source/xml_parser.c204
-rw-r--r--contrib/restricted/aws/aws-c-common/ya.make4
5 files changed, 219 insertions, 43 deletions
diff --git a/contrib/restricted/aws/aws-c-common/.yandex_meta/override.nix b/contrib/restricted/aws/aws-c-common/.yandex_meta/override.nix
index 3fa122ffab4..c166a09ab17 100644
--- a/contrib/restricted/aws/aws-c-common/.yandex_meta/override.nix
+++ b/contrib/restricted/aws/aws-c-common/.yandex_meta/override.nix
@@ -1,10 +1,10 @@
pkgs: attrs: with pkgs; with attrs; rec {
- version = "0.14.1";
+ version = "0.14.2";
src = fetchFromGitHub {
owner = "awslabs";
repo = "aws-c-common";
rev = "v${version}";
- hash = "sha256-HRnMoWZ1VrIc3ZUQUNonB+bC5vOsdqOD/gN/ZIK4RIo=";
+ hash = "sha256-kfRymCcPnkd+JA0Vk3QGMv68bdmd8C+dv5etrhc8tDM=";
};
}
diff --git a/contrib/restricted/aws/aws-c-common/include/aws/common/byte_buf.h b/contrib/restricted/aws/aws-c-common/include/aws/common/byte_buf.h
index 58a44c6645c..594bca22dbb 100644
--- a/contrib/restricted/aws/aws-c-common/include/aws/common/byte_buf.h
+++ b/contrib/restricted/aws/aws-c-common/include/aws/common/byte_buf.h
@@ -23,6 +23,19 @@ AWS_PUSH_SANE_WARNING_LEVEL
* Note that this structure allocates memory at the buffer pointer only. The
* struct itself does not get dynamically allocated and must be either
* maintained or copied to avoid losing access to the memory.
+ *
+ * GROWABILITY CONTRACT:
+ * - When `allocator != NULL`: the buffer owns its memory and can be grown
+ * via aws_byte_buf_reserve / aws_byte_buf_append_dynamic / etc.
+ * - When `allocator == NULL`: the buffer's memory is externally owned
+ * (e.g. by a buffer pool, by static storage, or by a stack frame) and
+ * MUST NOT be reallocated. Functions that would grow the buffer
+ * (aws_byte_buf_reserve, aws_byte_buf_append_dynamic, etc.) fail with
+ * AWS_ERROR_INVALID_ARGUMENT when called on such a buffer.
+ *
+ * Callers that may receive a buffer of either kind (e.g. from a buffer
+ * pool ticket) should use aws_byte_buf_append_auto, which selects
+ * the right append path automatically.
*/
struct aws_byte_buf {
/* do not reorder this, this struct lines up nicely with windows buffer structures--saving us allocations.*/
@@ -415,6 +428,28 @@ AWS_COMMON_API
int aws_byte_buf_append_dynamic(struct aws_byte_buf *to, const struct aws_byte_cursor *from);
/**
+ * Copies `from` to `to`, selecting between static and dynamic append based
+ * on whether `to` has an allocator.
+ *
+ * - If `to->allocator != NULL`: uses aws_byte_buf_append_dynamic (grows
+ * the buffer as needed; same behavior as calling that function directly).
+ * - If `to->allocator == NULL`: uses aws_byte_buf_append (no grow; returns
+ * AWS_ERROR_DEST_COPY_TOO_SMALL if `from` does not fit in remaining
+ * capacity).
+ *
+ * This is intended for callers that receive a buffer from a source whose
+ * growability is not known at the call site — most commonly a buffer
+ * obtained from an aws_s3_buffer_pool ticket, where pool-backed tickets
+ * return a fixed-size buffer (allocator == NULL) and the default pool may
+ * return a growable one.
+ *
+ * `from` and `to` may be the same buffer, permitting copying a buffer
+ * into itself.
+ */
+AWS_COMMON_API
+int aws_byte_buf_append_auto(struct aws_byte_buf *to, const struct aws_byte_cursor *from);
+
+/**
* Copies `from` to `to`. If `to` is too small, the buffer will be grown appropriately and
* the old contents copied over, before the new contents are appended.
*
diff --git a/contrib/restricted/aws/aws-c-common/source/byte_buf.c b/contrib/restricted/aws/aws-c-common/source/byte_buf.c
index 59e789404d3..57915bba851 100644
--- a/contrib/restricted/aws/aws-c-common/source/byte_buf.c
+++ b/contrib/restricted/aws/aws-c-common/source/byte_buf.c
@@ -760,6 +760,21 @@ int aws_byte_buf_append_dynamic(struct aws_byte_buf *to, const struct aws_byte_c
return s_aws_byte_buf_append_dynamic(to, from, false);
}
+int aws_byte_buf_append_auto(struct aws_byte_buf *to, const struct aws_byte_cursor *from) {
+ AWS_PRECONDITION(aws_byte_buf_is_valid(to));
+ AWS_PRECONDITION(aws_byte_cursor_is_valid(from));
+
+ /*
+ * Buffers without an allocator are externally-owned (e.g. by a
+ * buffer pool); they cannot grow, so use the static append path.
+ * Buffers with an allocator can grow, so use the dynamic path.
+ */
+ if (to->allocator != NULL) {
+ return aws_byte_buf_append_dynamic(to, from);
+ }
+ return aws_byte_buf_append(to, from);
+}
+
int aws_byte_buf_append_dynamic_secure(struct aws_byte_buf *to, const struct aws_byte_cursor *from) {
return s_aws_byte_buf_append_dynamic(to, from, true);
}
diff --git a/contrib/restricted/aws/aws-c-common/source/xml_parser.c b/contrib/restricted/aws/aws-c-common/source/xml_parser.c
index a32c602f18e..3be597a8742 100644
--- a/contrib/restricted/aws/aws-c-common/source/xml_parser.c
+++ b/contrib/restricted/aws/aws-c-common/source/xml_parser.c
@@ -40,6 +40,11 @@ static int s_load_node_decl(
AWS_PRECONDITION(decl_body);
AWS_PRECONDITION(node);
+ if (decl_body->len == 0) {
+ AWS_LOGF_ERROR(AWS_LS_COMMON_XML_PARSER, "XML document is invalid.");
+ return aws_raise_error(AWS_ERROR_INVALID_XML);
+ }
+
node->is_empty = decl_body->ptr[decl_body->len - 1] == '/';
struct aws_array_list splits;
@@ -159,6 +164,77 @@ clean_up:
return parser.error;
}
+/* Returns true if the byte can follow a tag name in a start or empty-element tag. */
+static bool s_is_tag_name_boundary(uint8_t c) {
+ return c == ' ' || c == '>' || c == '/' || c == '\t' || c == '\r' || c == '\n';
+}
+
+static struct aws_byte_cursor s_comment_prefix = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("<!--");
+static struct aws_byte_cursor s_comment_end = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("-->");
+static struct aws_byte_cursor s_cdata_prefix = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("<![CDATA[");
+static struct aws_byte_cursor s_cdata_end = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("]]>");
+static struct aws_byte_cursor s_pi_prefix = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("<?");
+static struct aws_byte_cursor s_pi_end = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("?>");
+static struct aws_byte_cursor s_self_close_suffix = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("/>");
+static struct aws_byte_cursor s_decl_prefix = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("<!");
+static struct aws_byte_cursor s_close_bracket = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL(">");
+static struct aws_byte_cursor s_closing_prefix = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("</");
+
+/*
+ * If `*input` points at a non-element construct (comment, CDATA, or PI), advances
+ * `*input` past the construct's closing delimiter, sets `*out_skipped = true`, and
+ * returns AWS_OP_SUCCESS.
+ *
+ * If `*input` does not start with a non-element construct, sets `*out_skipped = false`
+ * and returns AWS_OP_SUCCESS (caller should proceed with normal element handling).
+ *
+ * If the construct is unterminated (no closing delimiter found), returns AWS_OP_ERR
+ * and raises AWS_ERROR_INVALID_XML.
+ *
+ * WARNING: This function assumes `*input` starts with '<'. It will not produce correct
+ * results if called at an arbitrary position within a document.
+ */
+static int s_try_skip_non_element(struct aws_byte_cursor *input, bool *out_skipped) {
+ *out_skipped = false;
+
+ if (input->len == 0 || input->ptr[0] != '<') {
+ return AWS_OP_SUCCESS;
+ }
+
+ if (aws_byte_cursor_starts_with(input, &s_comment_prefix)) {
+ aws_byte_cursor_advance(input, s_comment_prefix.len);
+ struct aws_byte_cursor found;
+ if (aws_byte_cursor_find_exact(input, &s_comment_end, &found)) {
+ return aws_raise_error(AWS_ERROR_INVALID_XML);
+ }
+ aws_byte_cursor_advance(input, (found.ptr + s_comment_end.len) - input->ptr);
+ *out_skipped = true;
+ return AWS_OP_SUCCESS;
+ }
+ if (aws_byte_cursor_starts_with(input, &s_cdata_prefix)) {
+ aws_byte_cursor_advance(input, s_cdata_prefix.len);
+ struct aws_byte_cursor found;
+ if (aws_byte_cursor_find_exact(input, &s_cdata_end, &found)) {
+ return aws_raise_error(AWS_ERROR_INVALID_XML);
+ }
+ aws_byte_cursor_advance(input, (found.ptr + s_cdata_end.len) - input->ptr);
+ *out_skipped = true;
+ return AWS_OP_SUCCESS;
+ }
+ if (aws_byte_cursor_starts_with(input, &s_pi_prefix)) {
+ aws_byte_cursor_advance(input, s_pi_prefix.len);
+ struct aws_byte_cursor found;
+ if (aws_byte_cursor_find_exact(input, &s_pi_end, &found)) {
+ return aws_raise_error(AWS_ERROR_INVALID_XML);
+ }
+ aws_byte_cursor_advance(input, (found.ptr + s_pi_end.len) - input->ptr);
+ *out_skipped = true;
+ return AWS_OP_SUCCESS;
+ }
+
+ return AWS_OP_SUCCESS;
+}
+
int s_advance_to_closing_tag(
struct aws_xml_parser *parser,
struct aws_xml_node *node,
@@ -208,45 +284,68 @@ int s_advance_to_closing_tag(
aws_byte_buf_append(&closing_cmp_buf, &node->name);
aws_byte_buf_append(&closing_cmp_buf, &close_bracket);
- size_t depth_count = 1;
struct aws_byte_cursor to_find_open = aws_byte_cursor_from_buf(&open_cmp_buf);
struct aws_byte_cursor to_find_close = aws_byte_cursor_from_buf(&closing_cmp_buf);
- struct aws_byte_cursor close_find_result;
- AWS_ZERO_STRUCT(close_find_result);
- do {
- if (aws_byte_cursor_find_exact(&parser->doc, &to_find_close, &close_find_result)) {
- AWS_LOGF_ERROR(AWS_LS_COMMON_XML_PARSER, "XML document is invalid.");
- return aws_raise_error(AWS_ERROR_INVALID_XML);
+
+ /* Single forward scan: jump between '<' characters, tracking nesting depth. */
+ size_t depth = 1;
+ while (parser->doc.len > 0) {
+ const uint8_t *open = memchr(parser->doc.ptr, '<', parser->doc.len);
+ if (!open) {
+ break;
}
+ aws_byte_cursor_advance(&parser->doc, open - parser->doc.ptr);
- /* if we find an opening node with the same name, before the closing tag keep going. */
- struct aws_byte_cursor open_find_result;
- AWS_ZERO_STRUCT(open_find_result);
+ /* Skip non-element constructs (comments, CDATA, PI). */
+ bool skipped = false;
+ if (s_try_skip_non_element(&parser->doc, &skipped)) {
+ AWS_LOGF_ERROR(AWS_LS_COMMON_XML_PARSER, "XML document is invalid.");
+ return AWS_OP_ERR;
+ }
+ if (skipped) {
+ continue;
+ }
- while (parser->doc.len) {
- if (!aws_byte_cursor_find_exact(&parser->doc, &to_find_open, &open_find_result)) {
- if (open_find_result.ptr < close_find_result.ptr) {
- size_t skip_len = open_find_result.ptr - parser->doc.ptr;
- aws_byte_cursor_advance(&parser->doc, skip_len + 1);
- depth_count++;
- continue;
+ /* Check for closing tag. */
+ if (aws_byte_cursor_starts_with(&parser->doc, &to_find_close)) {
+ depth--;
+ if (depth == 0) {
+ size_t len = parser->doc.ptr - node->doc_at_body.ptr;
+ if (out_body) {
+ *out_body = aws_byte_cursor_from_array(node->doc_at_body.ptr, len);
}
+ aws_byte_cursor_advance(&parser->doc, to_find_close.len);
+ return parser->error;
}
- size_t skip_len = close_find_result.ptr - parser->doc.ptr;
-
- aws_byte_cursor_advance(&parser->doc, skip_len + closing_cmp_buf.len);
- depth_count--;
- break;
+ aws_byte_cursor_advance(&parser->doc, to_find_close.len);
+ continue;
}
- } while (depth_count > 0);
- size_t len = close_find_result.ptr - node->doc_at_body.ptr;
+ /* Check for opening tag with same name. */
+ if (aws_byte_cursor_starts_with(&parser->doc, &to_find_open)) {
- if (out_body) {
- *out_body = aws_byte_cursor_from_array(node->doc_at_body.ptr, len);
+ struct aws_byte_cursor after_open = parser->doc;
+ aws_byte_cursor_advance(&after_open, to_find_open.len);
+
+ if (after_open.len > 0 && s_is_tag_name_boundary(*after_open.ptr)) {
+ /* Check for self-closing tag (e.g. <a/>) — does not increment depth. */
+ if (!aws_byte_cursor_starts_with(&after_open, &s_self_close_suffix)) {
+ depth++;
+ }
+ }
+ /* Advance past the '<' regardless — the name boundary / self-close checks
+ * only determine whether depth increments; we always move forward. */
+ aws_byte_cursor_advance(&parser->doc, 1);
+ continue;
+ }
+
+ /* Some other '<' — skip past it. */
+ aws_byte_cursor_advance(&parser->doc, 1);
}
- return parser->error;
+ AWS_LOGF_ERROR(AWS_LS_COMMON_XML_PARSER, "XML document is invalid.");
+ parser->error = aws_raise_error(AWS_ERROR_INVALID_XML);
+ return AWS_OP_ERR;
}
int aws_xml_node_as_body(struct aws_xml_node *node, struct aws_byte_cursor *out_body) {
@@ -275,7 +374,7 @@ int aws_xml_node_traverse(
size_t doc_depth = aws_array_list_length(&parser->callback_stack);
if (doc_depth >= parser->max_depth) {
- AWS_LOGF_ERROR(AWS_LS_COMMON_XML_PARSER, "XML document exceeds max depth.");
+ AWS_LOGF_ERROR(AWS_LS_COMMON_XML_PARSER, "XML document exceeds max depth of %zu.", parser->max_depth);
aws_raise_error(AWS_ERROR_INVALID_XML);
goto error;
}
@@ -285,37 +384,64 @@ int aws_xml_node_traverse(
/* look for the next node at the current level. do this until we encounter the parent node's
* closing tag. */
while (!parser->error) {
- const uint8_t *next_location = memchr(parser->doc.ptr, '<', parser->doc.len);
+ const uint8_t *open = memchr(parser->doc.ptr, '<', parser->doc.len);
- if (!next_location) {
+ if (!open) {
AWS_LOGF_ERROR(AWS_LS_COMMON_XML_PARSER, "XML document is invalid.");
aws_raise_error(AWS_ERROR_INVALID_XML);
goto error;
}
- const uint8_t *end_location = memchr(parser->doc.ptr, '>', parser->doc.len);
+ /* Advance to the '<'. Everything leading up to the `<` is disregarded. */
+ aws_byte_cursor_advance(&parser->doc, open - parser->doc.ptr);
- if (!end_location || next_location >= end_location) {
+ /* Skip CDATA, comments, and processing instructions — they are not elements. */
+ bool skipped = false;
+ if (s_try_skip_non_element(&parser->doc, &skipped)) {
AWS_LOGF_ERROR(AWS_LS_COMMON_XML_PARSER, "XML document is invalid.");
- aws_raise_error(AWS_ERROR_INVALID_XML);
goto error;
}
+ if (skipped) {
+ continue;
+ }
- bool parent_closed = false;
+ /* Handle other <! declarations (e.g. <!DOCTYPE) not covered by the helper — skip to closing >. */
+ if (aws_byte_cursor_starts_with(&parser->doc, &s_decl_prefix)) {
+ struct aws_byte_cursor found;
+ if (aws_byte_cursor_find_exact(&parser->doc, &s_close_bracket, &found)) {
+ AWS_LOGF_ERROR(AWS_LS_COMMON_XML_PARSER, "XML document is invalid.");
+ aws_raise_error(AWS_ERROR_INVALID_XML);
+ goto error;
+ }
+ aws_byte_cursor_advance(&parser->doc, (found.ptr + 1) - parser->doc.ptr);
+ continue;
+ }
- if (*(next_location + 1) == '/') {
- parent_closed = true;
+ /* parser->doc.ptr is now at '<'. Find the closing '>'. */
+ if (parser->doc.len < 2) {
+ AWS_LOGF_ERROR(AWS_LS_COMMON_XML_PARSER, "XML document is invalid.");
+ aws_raise_error(AWS_ERROR_INVALID_XML);
+ goto error;
}
+ const uint8_t *end_location = memchr(parser->doc.ptr + 1, '>', parser->doc.len - 1);
+
+ if (!end_location) {
+ AWS_LOGF_ERROR(AWS_LS_COMMON_XML_PARSER, "XML document is invalid.");
+ aws_raise_error(AWS_ERROR_INVALID_XML);
+ goto error;
+ }
+
+ bool parent_closed = aws_byte_cursor_starts_with(&parser->doc, &s_closing_prefix);
+
+ size_t node_name_len = end_location - parser->doc.ptr;
+ struct aws_byte_cursor decl_body = aws_byte_cursor_from_array(parser->doc.ptr + 1, node_name_len - 1);
- size_t node_name_len = end_location - next_location;
aws_byte_cursor_advance(&parser->doc, end_location - parser->doc.ptr + 1);
if (parent_closed) {
break;
}
- struct aws_byte_cursor decl_body = aws_byte_cursor_from_array(next_location + 1, node_name_len - 1);
-
struct aws_xml_node next_node = {
.parser = parser,
.doc_at_body = parser->doc,
diff --git a/contrib/restricted/aws/aws-c-common/ya.make b/contrib/restricted/aws/aws-c-common/ya.make
index 78c40482351..94b5189c1a0 100644
--- a/contrib/restricted/aws/aws-c-common/ya.make
+++ b/contrib/restricted/aws/aws-c-common/ya.make
@@ -12,9 +12,9 @@ LICENSE(
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-VERSION(0.14.1)
+VERSION(0.14.2)
-ORIGINAL_SOURCE(https://github.com/awslabs/aws-c-common/archive/v0.14.1.tar.gz)
+ORIGINAL_SOURCE(https://github.com/awslabs/aws-c-common/archive/v0.14.2.tar.gz)
ADDINCL(
GLOBAL contrib/restricted/aws/aws-c-common/generated/include