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

fix empty xml node handling #1168

Merged
merged 5 commits into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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
1 change: 1 addition & 0 deletions include/aws/common/private/xml_parser_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ struct aws_xml_node {
struct aws_array_list attributes;
struct aws_byte_cursor doc_at_body;
bool processed;
bool is_empty;
};

struct aws_xml_parser {
Expand Down
10 changes: 10 additions & 0 deletions source/xml_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ static int s_load_node_decl(
AWS_PRECONDITION(decl_body);
AWS_PRECONDITION(node);

node->is_empty = decl_body->ptr[decl_body->len - 1] == '/';

struct aws_array_list splits;
AWS_ZERO_STRUCT(splits);

Expand Down Expand Up @@ -158,6 +160,14 @@ int s_advance_to_closing_tag(
AWS_PRECONDITION(parser);
AWS_PRECONDITION(node);

if (node->is_empty) {
if (out_body) {
out_body->ptr = NULL;
out_body->len = 0;
}
return AWS_OP_SUCCESS;
}

/* 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};
Expand Down
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,7 @@ add_test_case(xml_parser_nested_node_same_name_test)
add_test_case(xml_parser_nested_node_deep_recursion_test)
add_test_case(xml_parser_too_many_attributes_test)
add_test_case(xml_parser_name_too_long_test)
add_test_case(xml_parser_child_empty_tag)

add_test_case(test_thread_scheduler_ordering)
add_test_case(test_thread_scheduler_happy_path_cancellation)
Expand Down
34 changes: 34 additions & 0 deletions tests/xml_parser_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,40 @@ static int s_xml_parser_siblings_with_text_test(struct aws_allocator *allocator,

AWS_TEST_CASE(xml_parser_siblings_with_text, s_xml_parser_siblings_with_text_test)

const char *siblings_with_empty_tag = "<?xml version=\"1.0\" "
"encoding=\"UTF-8\"?><rootNode><child1 /><child2>TestBody2</child2></rootNode>";

static int s_xml_parser_child_empty_tag(struct aws_allocator *allocator, void *ctx) {
(void)ctx;
struct sibling_text_capture capture;
AWS_ZERO_STRUCT(capture);
DmitriyMusatkin marked this conversation as resolved.
Show resolved Hide resolved

struct aws_xml_parser_options options = {
.doc = aws_byte_cursor_from_c_str(siblings_with_empty_tag),
.on_root_encountered = s_root_with_child_siblings,
.user_data = &capture,
};
ASSERT_SUCCESS(aws_xml_parse(allocator, &options));

const char expected_name1[] = "child1";

const char expected_name2[] = "child2";
const char expected_value2[] = "TestBody2";

ASSERT_BIN_ARRAYS_EQUALS(
expected_name1, sizeof(expected_name1) - 1, capture.node_name1.ptr, capture.node_name1.len);
ASSERT_PTR_EQUALS(capture.capture1.ptr, NULL);
ASSERT_UINT_EQUALS(capture.capture1.len, 0);

ASSERT_BIN_ARRAYS_EQUALS(
expected_name2, sizeof(expected_name2) - 1, capture.node_name2.ptr, capture.node_name2.len);
ASSERT_BIN_ARRAYS_EQUALS(expected_value2, sizeof(expected_value2) - 1, capture.capture2.ptr, capture.capture2.len);

return AWS_OP_SUCCESS;
}

AWS_TEST_CASE(xml_parser_child_empty_tag, s_xml_parser_child_empty_tag)

const char *preamble_and_attributes =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<!DOCTYPE html \n"
Expand Down
Loading