Skip to content

Commit aaa2f11

Browse files
authored
Fix invalid XML Buffer Overflow Error (#1201)
1 parent 8c9200c commit aaa2f11

File tree

5 files changed

+38
-7
lines changed

5 files changed

+38
-7
lines changed
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
#Wed Apr 01 11:18:00 PDT 2020
1+
#Fri May 09 10:40:15 PDT 2025
22
distributionBase=GRADLE_USER_HOME
33
distributionPath=wrapper/dists
4+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
45
zipStoreBase=GRADLE_USER_HOME
56
zipStorePath=wrapper/dists
6-
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip

include/aws/common/xml_parser.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* SPDX-License-Identifier: Apache-2.0.
77
*/
88

9+
/* WARNING: This is not a public API. It is only intended for use within the aws-c libraries. */
910
#include <aws/common/array_list.h>
1011
#include <aws/common/byte_buf.h>
1112

source/xml_parser.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,12 @@ int aws_xml_parse(struct aws_allocator *allocator, const struct aws_xml_parser_o
127127
goto clean_up;
128128
}
129129

130+
if (start > location) {
131+
AWS_LOGF_ERROR(AWS_LS_COMMON_XML_PARSER, "XML document is invalid.");
132+
parser.error = aws_raise_error(AWS_ERROR_INVALID_XML);
133+
goto clean_up;
134+
}
135+
130136
aws_byte_cursor_advance(&parser.doc, start - parser.doc.ptr);
131137
/* if these are preamble statements, burn them. otherwise don't seek at all
132138
* and assume it's just the doc with no preamble statements. */
@@ -227,6 +233,7 @@ int s_advance_to_closing_tag(
227233
}
228234
}
229235
size_t skip_len = close_find_result.ptr - parser->doc.ptr;
236+
230237
aws_byte_cursor_advance(&parser->doc, skip_len + closing_cmp_buf.len);
231238
depth_count--;
232239
break;
@@ -288,7 +295,7 @@ int aws_xml_node_traverse(
288295

289296
const uint8_t *end_location = memchr(parser->doc.ptr, '>', parser->doc.len);
290297

291-
if (!end_location) {
298+
if (!end_location || next_location >= end_location) {
292299
AWS_LOGF_ERROR(AWS_LS_COMMON_XML_PARSER, "XML document is invalid.");
293300
aws_raise_error(AWS_ERROR_INVALID_XML);
294301
goto error;
@@ -301,7 +308,6 @@ int aws_xml_node_traverse(
301308
}
302309

303310
size_t node_name_len = end_location - next_location;
304-
305311
aws_byte_cursor_advance(&parser->doc, end_location - parser->doc.ptr + 1);
306312

307313
if (parent_closed) {
@@ -368,13 +374,14 @@ int s_node_next_sibling(struct aws_xml_parser *parser) {
368374
const uint8_t *next_location = memchr(parser->doc.ptr, '<', parser->doc.len);
369375

370376
if (!next_location) {
371-
return parser->error;
377+
AWS_LOGF_ERROR(AWS_LS_COMMON_XML_PARSER, "XML document is invalid.");
378+
return aws_raise_error(AWS_ERROR_INVALID_XML);
372379
}
373380

374381
aws_byte_cursor_advance(&parser->doc, next_location - parser->doc.ptr);
375382
const uint8_t *end_location = memchr(parser->doc.ptr, '>', parser->doc.len);
376383

377-
if (!end_location) {
384+
if (!end_location || next_location >= end_location) {
378385
AWS_LOGF_ERROR(AWS_LS_COMMON_XML_PARSER, "XML document is invalid.");
379386
return aws_raise_error(AWS_ERROR_INVALID_XML);
380387
}

tests/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,8 @@ add_test_case(run_command_test_bad_command)
460460

461461
add_test_case(cpuid_test)
462462

463-
add_test_case(xml_parser_root_with_text)
463+
add_test_case(xml_parser_root_with_text)
464+
add_test_case(xml_parser_malformed_end_node_character_before_start_test)
464465
add_test_case(xml_parser_child_with_text)
465466
add_test_case(xml_parser_siblings_with_text)
466467
add_test_case(xml_parser_preamble_and_attributes)

tests/xml_parser_test.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,28 @@ static int s_xml_parser_child_with_text_test(struct aws_allocator *allocator, vo
9595

9696
AWS_TEST_CASE(xml_parser_child_with_text, s_xml_parser_child_with_text_test)
9797

98+
const char *malformed_end_node_character_before_start =
99+
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><rootNode>><child1>TestBody</child1></rootNode>";
100+
101+
static int s_xml_parser_malformed_end_node_character_before_start_test(struct aws_allocator *allocator, void *ctx) {
102+
(void)ctx;
103+
struct child_text_capture capture;
104+
AWS_ZERO_STRUCT(capture);
105+
106+
struct aws_xml_parser_options options = {
107+
.doc = aws_byte_cursor_from_c_str(malformed_end_node_character_before_start),
108+
.on_root_encountered = s_root_with_child,
109+
.user_data = &capture,
110+
};
111+
ASSERT_ERROR(AWS_ERROR_INVALID_XML, aws_xml_parse(allocator, &options));
112+
113+
return AWS_OP_SUCCESS;
114+
}
115+
116+
AWS_TEST_CASE(
117+
xml_parser_malformed_end_node_character_before_start_test,
118+
s_xml_parser_malformed_end_node_character_before_start_test)
119+
98120
const char *siblings_with_text =
99121
"<?xml version=\"1.0\" "
100122
"encoding=\"UTF-8\"?><rootNode><child1>TestBody</child1><child2>TestBody2</child2></rootNode>";

0 commit comments

Comments
 (0)