diff options
author | thegeorg <[email protected]> | 2025-05-12 15:51:24 +0300 |
---|---|---|
committer | thegeorg <[email protected]> | 2025-05-12 16:06:27 +0300 |
commit | d629bb70c8773d2c0c43f5088ddbb5a86d8c37ea (patch) | |
tree | 4f678e0d65ad08c800db21c657d3b0f71fafed06 /contrib/restricted/aws/aws-c-common/source/xml_parser.c | |
parent | 92c4b696d7a1c03d54e13aff7a7c20a078d90dd7 (diff) |
Update contrib/restricted/aws libraries to nixpkgs 24.05
commit_hash:f8083acb039e6005e820cdee77b84e0a6b6c6d6d
Diffstat (limited to 'contrib/restricted/aws/aws-c-common/source/xml_parser.c')
-rw-r--r-- | contrib/restricted/aws/aws-c-common/source/xml_parser.c | 193 |
1 files changed, 71 insertions, 122 deletions
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 ac238cdfaf3..e1b5807401d 100644 --- a/contrib/restricted/aws/aws-c-common/source/xml_parser.c +++ b/contrib/restricted/aws/aws-c-common/source/xml_parser.c @@ -21,45 +21,6 @@ struct cb_stack_data { void *user_data; }; -struct aws_xml_parser *aws_xml_parser_new( - struct aws_allocator *allocator, - const struct aws_xml_parser_options *options) { - - AWS_PRECONDITION(allocator); - AWS_PRECONDITION(options); - - struct aws_xml_parser *parser = aws_mem_calloc(allocator, 1, sizeof(struct aws_xml_parser)); - - if (parser == NULL) { - return NULL; - } - - parser->allocator = allocator; - parser->doc = options->doc; - - parser->max_depth = s_max_document_depth; - parser->error = AWS_OP_SUCCESS; - - if (options->max_depth) { - parser->max_depth = options->max_depth; - } - - if (aws_array_list_init_dynamic(&parser->callback_stack, allocator, 4, sizeof(struct cb_stack_data))) { - aws_mem_release(allocator, parser); - return NULL; - } - - return parser; -} - -void aws_xml_parser_destroy(struct aws_xml_parser *parser) { - AWS_PRECONDITION(parser); - - aws_array_list_clean_up(&parser->callback_stack); - - aws_mem_release(parser->allocator, parser); -} - int s_node_next_sibling(struct aws_xml_parser *parser); static bool s_double_quote_fn(uint8_t value) { @@ -90,14 +51,14 @@ static int s_load_node_decl( * we limit to 10 attributes, if this is exceeded we consider it invalid document. */ if (aws_byte_cursor_split_on_char(decl_body, ' ', &splits)) { AWS_LOGF_ERROR(AWS_LS_COMMON_XML_PARSER, "XML document is invalid."); - return aws_raise_error(AWS_ERROR_MALFORMED_INPUT_STRING); + return aws_raise_error(AWS_ERROR_INVALID_XML); } size_t splits_count = aws_array_list_length(&splits); if (splits_count < 1) { AWS_LOGF_ERROR(AWS_LS_COMMON_XML_PARSER, "XML document is invalid."); - return aws_raise_error(AWS_ERROR_MALFORMED_INPUT_STRING); + return aws_raise_error(AWS_ERROR_INVALID_XML); } aws_array_list_get_at(&splits, &node->name, 0); @@ -134,43 +95,43 @@ static int s_load_node_decl( return AWS_OP_SUCCESS; } -int aws_xml_parser_parse( - struct aws_xml_parser *parser, - aws_xml_parser_on_node_encountered_fn *on_node_encountered, - void *user_data) { - - AWS_PRECONDITION(parser); +int aws_xml_parse(struct aws_allocator *allocator, const struct aws_xml_parser_options *options) { - if (on_node_encountered == NULL) { - AWS_LOGF_ERROR(AWS_LS_COMMON_XML_PARSER, "'on_node_encountered' argument for aws_xml_parser_parse is invalid."); - aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); - return AWS_OP_ERR; - } + AWS_PRECONDITION(allocator); + AWS_PRECONDITION(options); + AWS_PRECONDITION(options->on_root_encountered); - aws_array_list_clear(&parser->callback_stack); + struct aws_xml_parser parser = { + .allocator = allocator, + .doc = options->doc, + .max_depth = options->max_depth ? options->max_depth : s_max_document_depth, + .error = AWS_OP_SUCCESS, + }; + aws_array_list_init_dynamic(&parser.callback_stack, allocator, 4, sizeof(struct cb_stack_data)); /* burn everything that precedes the actual xml nodes. */ - while (parser->doc.len) { - const uint8_t *start = memchr(parser->doc.ptr, '<', parser->doc.len); + while (parser.doc.len) { + const uint8_t *start = memchr(parser.doc.ptr, '<', parser.doc.len); if (!start) { AWS_LOGF_ERROR(AWS_LS_COMMON_XML_PARSER, "XML document is invalid."); - return aws_raise_error(AWS_ERROR_MALFORMED_INPUT_STRING); + parser.error = aws_raise_error(AWS_ERROR_INVALID_XML); + goto clean_up; } - const uint8_t *location = memchr(parser->doc.ptr, '>', parser->doc.len); - + const uint8_t *location = memchr(parser.doc.ptr, '>', parser.doc.len); if (!location) { AWS_LOGF_ERROR(AWS_LS_COMMON_XML_PARSER, "XML document is invalid."); - return aws_raise_error(AWS_ERROR_MALFORMED_INPUT_STRING); + parser.error = aws_raise_error(AWS_ERROR_INVALID_XML); + goto clean_up; } - aws_byte_cursor_advance(&parser->doc, start - parser->doc.ptr); + aws_byte_cursor_advance(&parser.doc, start - parser.doc.ptr); /* if these are preamble statements, burn them. otherwise don't seek at all * and assume it's just the doc with no preamble statements. */ - if (*(parser->doc.ptr + 1) == '?' || *(parser->doc.ptr + 1) == '!') { + if (*(parser.doc.ptr + 1) == '?' || *(parser.doc.ptr + 1) == '!') { /* nobody cares about the preamble */ - size_t advance = location - parser->doc.ptr + 1; - aws_byte_cursor_advance(&parser->doc, advance); + size_t advance = location - parser.doc.ptr + 1; + aws_byte_cursor_advance(&parser.doc, advance); } else { break; } @@ -178,12 +139,16 @@ int aws_xml_parser_parse( /* now we should be at the start of the actual document. */ struct cb_stack_data stack_data = { - .cb = on_node_encountered, - .user_data = user_data, + .cb = options->on_root_encountered, + .user_data = options->user_data, }; - AWS_FATAL_ASSERT(!aws_array_list_push_back(&parser->callback_stack, &stack_data)); - return s_node_next_sibling(parser); + aws_array_list_push_back(&parser.callback_stack, &stack_data); + parser.error = s_node_next_sibling(&parser); + +clean_up: + aws_array_list_clean_up(&parser.callback_stack); + return parser.error; } int s_advance_to_closing_tag( @@ -205,13 +170,13 @@ int s_advance_to_closing_tag( if (closing_name_len > node->doc_at_body.len) { AWS_LOGF_ERROR(AWS_LS_COMMON_XML_PARSER, "XML document is invalid."); - parser->error = aws_raise_error(AWS_ERROR_MALFORMED_INPUT_STRING); + parser->error = aws_raise_error(AWS_ERROR_INVALID_XML); return AWS_OP_ERR; } if (sizeof(name_close) < closing_name_len) { AWS_LOGF_ERROR(AWS_LS_COMMON_XML_PARSER, "XML document is invalid."); - parser->error = aws_raise_error(AWS_ERROR_MALFORMED_INPUT_STRING); + parser->error = aws_raise_error(AWS_ERROR_INVALID_XML); return AWS_OP_ERR; } @@ -235,7 +200,7 @@ int s_advance_to_closing_tag( 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_MALFORMED_INPUT_STRING); + return aws_raise_error(AWS_ERROR_INVALID_XML); } /* if we find an opening node with the same name, before the closing tag keep going. */ @@ -267,29 +232,24 @@ int s_advance_to_closing_tag( return parser->error; } -int aws_xml_node_as_body(struct aws_xml_parser *parser, struct aws_xml_node *node, struct aws_byte_cursor *out_body) { - AWS_PRECONDITION(parser); +int aws_xml_node_as_body(struct aws_xml_node *node, struct aws_byte_cursor *out_body) { AWS_PRECONDITION(node); + AWS_FATAL_ASSERT(!node->processed && "XML node can be traversed, or read as body, but not both."); node->processed = true; - return s_advance_to_closing_tag(parser, node, out_body); + return s_advance_to_closing_tag(node->parser, node, out_body); } int aws_xml_node_traverse( - struct aws_xml_parser *parser, struct aws_xml_node *node, aws_xml_parser_on_node_encountered_fn *on_node_encountered, void *user_data) { - AWS_PRECONDITION(parser); AWS_PRECONDITION(node); + AWS_PRECONDITION(on_node_encountered); - if (on_node_encountered == NULL) { - AWS_LOGF_ERROR( - AWS_LS_COMMON_XML_PARSER, "Callback 'on_node_encountered' for aws_xml_node_traverse is invalid."); - aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); - return AWS_OP_ERR; - } + struct aws_xml_parser *parser = node->parser; + AWS_FATAL_ASSERT(!node->processed && "XML node can be traversed, or read as body, but not both."); node->processed = true; struct cb_stack_data stack_data = { .cb = on_node_encountered, @@ -298,32 +258,30 @@ 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 is invalid."); - parser->error = aws_raise_error(AWS_ERROR_MALFORMED_INPUT_STRING); - return AWS_OP_ERR; + AWS_LOGF_ERROR(AWS_LS_COMMON_XML_PARSER, "XML document exceeds max depth."); + aws_raise_error(AWS_ERROR_INVALID_XML); + goto error; } - if (aws_array_list_push_back(&parser->callback_stack, &stack_data)) { - AWS_LOGF_ERROR(AWS_LS_COMMON_XML_PARSER, "XML document is invalid."); - parser->error = aws_raise_error(AWS_ERROR_MALFORMED_INPUT_STRING); - return AWS_OP_ERR; - } + aws_array_list_push_back(&parser->callback_stack, &stack_data); /* look for the next node at the current level. do this until we encounter the parent node's * closing tag. */ - while (!parser->stop_parsing && !parser->error) { + while (!parser->error) { const uint8_t *next_location = memchr(parser->doc.ptr, '<', parser->doc.len); if (!next_location) { AWS_LOGF_ERROR(AWS_LS_COMMON_XML_PARSER, "XML document is invalid."); - return aws_raise_error(AWS_ERROR_MALFORMED_INPUT_STRING); + aws_raise_error(AWS_ERROR_INVALID_XML); + goto error; } const uint8_t *end_location = memchr(parser->doc.ptr, '>', parser->doc.len); if (!end_location) { AWS_LOGF_ERROR(AWS_LS_COMMON_XML_PARSER, "XML document is invalid."); - return aws_raise_error(AWS_ERROR_MALFORMED_INPUT_STRING); + aws_raise_error(AWS_ERROR_INVALID_XML); + goto error; } bool parent_closed = false; @@ -343,6 +301,7 @@ int aws_xml_node_traverse( 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, .processed = false, }; @@ -351,38 +310,29 @@ int aws_xml_node_traverse( return AWS_OP_ERR; } - if (!on_node_encountered(parser, &next_node, user_data)) { - parser->stop_parsing = true; - return parser->error; + if (on_node_encountered(&next_node, user_data)) { + goto error; } /* if the user simply returned while skipping the node altogether, go ahead and do the skip over. */ - if (!parser->stop_parsing && !next_node.processed) { + if (!next_node.processed) { if (s_advance_to_closing_tag(parser, &next_node, NULL)) { - return AWS_OP_ERR; + goto error; } } } - if (parser->stop_parsing) { - return parser->error; - } - aws_array_list_pop_back(&parser->callback_stack); return parser->error; + +error: + parser->error = AWS_OP_ERR; + return parser->error; } -int aws_xml_node_get_name(const struct aws_xml_node *node, struct aws_byte_cursor *out_name) { +struct aws_byte_cursor aws_xml_node_get_name(const struct aws_xml_node *node) { AWS_PRECONDITION(node); - - if (out_name == NULL) { - AWS_LOGF_ERROR(AWS_LS_COMMON_XML_PARSER, "'out_name' argument for aws_xml_node_get_name is invalid."); - aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); - return AWS_OP_ERR; - } - - *out_name = node->name; - return AWS_OP_SUCCESS; + return node->name; } size_t aws_xml_node_get_num_attributes(const struct aws_xml_node *node) { @@ -390,19 +340,15 @@ size_t aws_xml_node_get_num_attributes(const struct aws_xml_node *node) { return aws_array_list_length(&node->attributes); } -int aws_xml_node_get_attribute( - const struct aws_xml_node *node, - size_t attribute_index, - struct aws_xml_attribute *out_attribute) { +struct aws_xml_attribute aws_xml_node_get_attribute(const struct aws_xml_node *node, size_t attribute_index) { AWS_PRECONDITION(node); - if (out_attribute == NULL) { - AWS_LOGF_ERROR(AWS_LS_COMMON_XML_PARSER, "'out_attribute' argument for aws_xml_node_get_attribute is invalid."); - aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); - return AWS_OP_ERR; + struct aws_xml_attribute attribute; + if (aws_array_list_get_at(&node->attributes, &attribute, attribute_index)) { + AWS_FATAL_ASSERT(0 && "Invalid XML attribute index"); } - return aws_array_list_get_at(&node->attributes, out_attribute, attribute_index); + return attribute; } /* advance the parser to the next sibling node.*/ @@ -420,7 +366,7 @@ int s_node_next_sibling(struct aws_xml_parser *parser) { if (!end_location) { AWS_LOGF_ERROR(AWS_LS_COMMON_XML_PARSER, "XML document is invalid."); - return aws_raise_error(AWS_ERROR_MALFORMED_INPUT_STRING); + return aws_raise_error(AWS_ERROR_INVALID_XML); } size_t node_name_len = end_location - next_location; @@ -429,6 +375,7 @@ int s_node_next_sibling(struct aws_xml_parser *parser) { struct aws_byte_cursor node_decl_body = aws_byte_cursor_from_array(next_location + 1, node_name_len - 1); struct aws_xml_node sibling_node = { + .parser = parser, .doc_at_body = parser->doc, .processed = false, }; @@ -442,7 +389,9 @@ int s_node_next_sibling(struct aws_xml_parser *parser) { aws_array_list_back(&parser->callback_stack, &stack_data); AWS_FATAL_ASSERT(stack_data.cb); - parser->stop_parsing = !stack_data.cb(parser, &sibling_node, stack_data.user_data); + if (stack_data.cb(&sibling_node, stack_data.user_data)) { + return AWS_OP_ERR; + } /* if the user simply returned while skipping the node altogether, go ahead and do the skip over. */ if (!sibling_node.processed) { |