in source/xml_parser.c [189:268]
int s_advance_to_closing_tag(
struct aws_xml_parser *parser,
struct aws_xml_node *node,
struct aws_byte_cursor *out_body) {
AWS_PRECONDITION(parser);
AWS_PRECONDITION(node);
/* currently the max node name is 256 characters. This is arbitrary, but should be enough
* for our uses. If we ever generalize this, we'll have to come back and rethink this. */
uint8_t name_close[MAX_NAME_LEN + NODE_CLOSE_OVERHEAD] = {0};
uint8_t name_open[MAX_NAME_LEN + NODE_CLOSE_OVERHEAD] = {0};
struct aws_byte_buf closing_cmp_buf = aws_byte_buf_from_empty_array(name_close, sizeof(name_close));
struct aws_byte_buf open_cmp_buf = aws_byte_buf_from_empty_array(name_open, sizeof(name_open));
size_t closing_name_len = node->name.len + NODE_CLOSE_OVERHEAD;
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);
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);
return AWS_OP_ERR;
}
struct aws_byte_cursor open_bracket = aws_byte_cursor_from_c_str("<");
struct aws_byte_cursor close_token = aws_byte_cursor_from_c_str("/");
struct aws_byte_cursor close_bracket = aws_byte_cursor_from_c_str(">");
aws_byte_buf_append(&open_cmp_buf, &open_bracket);
aws_byte_buf_append(&open_cmp_buf, &node->name);
aws_byte_buf_append(&closing_cmp_buf, &open_bracket);
aws_byte_buf_append(&closing_cmp_buf, &close_token);
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_MALFORMED_INPUT_STRING);
}
/* 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);
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;
}
}
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;
}
} while (depth_count > 0);
size_t len = close_find_result.ptr - node->doc_at_body.ptr;
if (out_body) {
*out_body = aws_byte_cursor_from_array(node->doc_at_body.ptr, len);
}
return parser->error;
}