mirror of
https://git.yoctoproject.org/poky
synced 2026-09-29 07:36:20 +02:00
Backport patches from [1] also mentioned in [2]. [1] https://github.com/libexpat/libexpat/pull/1216 [2] https://security-tracker.debian.org/tracker/CVE-2026-45186 (From OE-Core rev: aa81f5c9a7e1243b9467b51388798dc0dd5a7aad) Signed-off-by: Theo Gaige <tgaige.opensource@witekio.com> Reviewed-by: Bruno Vernay <bruno.vernay@se.com> Signed-off-by: Yoann Congal <yoann.congal@smile.fr> Signed-off-by: Paul Barker <paul@pbarker.dev>
319 lines
11 KiB
Diff
319 lines
11 KiB
Diff
From ba12af3b3ffd98b9e31c3a01a20d392c89aa974e Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Berkay=20Eren=20=C3=9Cr=C3=BCn?= <berkay.ueruen@siemens.com>
|
|
Date: Fri, 13 Mar 2026 13:27:31 +0100
|
|
Subject: [PATCH 2/7] test(attlist): Cover duplicate attribute names
|
|
|
|
Co-authored-by: Sebastian Pipping <sebastian@pipping.org>
|
|
(cherry picked from commit e569f47181c43dca5d262089e541ddf9a9c09927)
|
|
|
|
CVE: CVE-2026-45186
|
|
Upstream-Status: Backport [https://github.com/libexpat/libexpat/pull/1216/commits/e569f47181c43dca5d262089e541ddf9a9c09927]
|
|
Signed-off-by: Theo Gaige <tgaige.opensource@witekio.com>
|
|
---
|
|
tests/basic_tests.c | 282 ++++++++++++++++++++++++++++++++++++++++++++
|
|
1 file changed, 282 insertions(+)
|
|
|
|
diff --git a/tests/basic_tests.c b/tests/basic_tests.c
|
|
index d6edb16..907a458 100644
|
|
--- a/tests/basic_tests.c
|
|
+++ b/tests/basic_tests.c
|
|
@@ -2462,6 +2462,279 @@ START_TEST(test_attributes) {
|
|
}
|
|
END_TEST
|
|
|
|
+START_TEST(test_duplicate_cdata_attribute) {
|
|
+ /*
|
|
+ https://www.w3.org/TR/xml/#attdecls
|
|
+
|
|
+ Test the following statement from the linked specification:
|
|
+ When more than one definition is provided for the same attribute of a given
|
|
+ element type, the first declaration is binding and later declarations are
|
|
+ ignored.
|
|
+ */
|
|
+
|
|
+ const char *text
|
|
+ = "<!DOCTYPE doc [\n"
|
|
+ " <!ATTLIST doc attribute CDATA 'expected' attribute CDATA 'ignored'>\n"
|
|
+ "]>\n"
|
|
+ "<doc/>\n";
|
|
+ AttrInfo doc_info[] = {{XCS("attribute"), XCS("expected")}, {NULL, NULL}};
|
|
+ ElementInfo info[]
|
|
+ = {{XCS("doc"), 0, 1, NULL, doc_info}, {NULL, 0, 0, NULL, NULL}};
|
|
+
|
|
+ XML_Parser parser = XML_ParserCreate(NULL);
|
|
+ assert_true(parser != NULL);
|
|
+
|
|
+ ParserAndElementInfo parserAndElementInfos = {
|
|
+ parser,
|
|
+ info,
|
|
+ };
|
|
+
|
|
+ XML_SetStartElementHandler(parser, counting_start_element_handler);
|
|
+ XML_SetUserData(parser, &parserAndElementInfos);
|
|
+
|
|
+ if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE)
|
|
+ != XML_STATUS_OK)
|
|
+ xml_failure(parser);
|
|
+
|
|
+ XML_ParserFree(parser);
|
|
+}
|
|
+END_TEST
|
|
+
|
|
+START_TEST(test_duplicate_id_attribute_1) {
|
|
+ /*
|
|
+ https://www.w3.org/TR/xml/#attdecls
|
|
+
|
|
+ Test the following statement from the linked specification:
|
|
+ When more than one definition is provided for the same attribute of a given
|
|
+ element type, the first declaration is binding and later declarations are
|
|
+ ignored.
|
|
+ */
|
|
+
|
|
+ const char *text
|
|
+ = "<!DOCTYPE doc [\n"
|
|
+ " <!ATTLIST doc identifier CDATA 'expected' identifier ID #REQUIRED>\n"
|
|
+ "]>\n"
|
|
+ "<doc/>\n";
|
|
+ AttrInfo doc_info[] = {{XCS("identifier"), XCS("expected")}, {NULL, NULL}};
|
|
+ ElementInfo info[]
|
|
+ = {{XCS("doc"), 0, 1, NULL, doc_info}, {NULL, 0, 0, NULL, NULL}};
|
|
+
|
|
+ XML_Parser parser = XML_ParserCreate(NULL);
|
|
+ assert_true(parser != NULL);
|
|
+
|
|
+ ParserAndElementInfo parserAndElementInfos = {
|
|
+ parser,
|
|
+ info,
|
|
+ };
|
|
+
|
|
+ XML_SetStartElementHandler(parser, counting_start_element_handler);
|
|
+ XML_SetUserData(parser, &parserAndElementInfos);
|
|
+
|
|
+ if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE)
|
|
+ != XML_STATUS_OK)
|
|
+ xml_failure(parser);
|
|
+
|
|
+ XML_ParserFree(parser);
|
|
+}
|
|
+END_TEST
|
|
+
|
|
+START_TEST(test_duplicate_id_attribute_2) {
|
|
+ /*
|
|
+ https://www.w3.org/TR/xml/#attdecls
|
|
+
|
|
+ Test the following statement from the linked specification:
|
|
+ When more than one definition is provided for the same attribute of a given
|
|
+ element type, the first declaration is binding and later declarations are
|
|
+ ignored.
|
|
+ */
|
|
+
|
|
+ const char *text
|
|
+ = "<!DOCTYPE doc [\n"
|
|
+ " <!ATTLIST doc identifier ID #REQUIRED identifier CDATA 'unexpected'>\n"
|
|
+ "]>\n"
|
|
+ "<doc/>\n";
|
|
+ AttrInfo doc_info[] = {{NULL, NULL}};
|
|
+
|
|
+ ElementInfo info[]
|
|
+ = {{XCS("doc"), 0, 0, NULL, doc_info}, {NULL, 0, 0, NULL, NULL}};
|
|
+
|
|
+ XML_Parser parser = XML_ParserCreate(NULL);
|
|
+ assert_true(parser != NULL);
|
|
+
|
|
+ ParserAndElementInfo parserAndElementInfos = {
|
|
+ parser,
|
|
+ info,
|
|
+ };
|
|
+
|
|
+ XML_SetStartElementHandler(parser, counting_start_element_handler);
|
|
+ XML_SetUserData(parser, &parserAndElementInfos);
|
|
+
|
|
+ if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE)
|
|
+ != XML_STATUS_OK)
|
|
+ xml_failure(parser);
|
|
+
|
|
+ XML_ParserFree(parser);
|
|
+}
|
|
+END_TEST
|
|
+
|
|
+START_TEST(test_duplicate_cdata_attribute_multiple_attlistdecl) {
|
|
+ /*
|
|
+ https://www.w3.org/TR/xml/#attdecls
|
|
+
|
|
+ Test the following statement from the linked specification:
|
|
+ When more than one AttlistDecl is provided for a given element type,
|
|
+ the contents of all those provided are merged.
|
|
+ */
|
|
+ const char *text = "<!DOCTYPE doc [\n"
|
|
+ " <!ATTLIST doc attribute CDATA 'expected'>\n"
|
|
+ " <!ATTLIST doc attribute CDATA 'ignored'>\n"
|
|
+ "]>\n"
|
|
+ "<doc/>\n";
|
|
+ AttrInfo doc_info[] = {{XCS("attribute"), XCS("expected")}, {NULL, NULL}};
|
|
+ ElementInfo info[]
|
|
+ = {{XCS("doc"), 0, 1, NULL, doc_info}, {NULL, 0, 0, NULL, NULL}};
|
|
+
|
|
+ XML_Parser parser = XML_ParserCreate(NULL);
|
|
+ assert_true(parser != NULL);
|
|
+
|
|
+ ParserAndElementInfo parserAndElementInfos = {
|
|
+ parser,
|
|
+ info,
|
|
+ };
|
|
+
|
|
+ XML_SetStartElementHandler(parser, counting_start_element_handler);
|
|
+ XML_SetUserData(parser, &parserAndElementInfos);
|
|
+
|
|
+ if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE)
|
|
+ != XML_STATUS_OK)
|
|
+ xml_failure(parser);
|
|
+
|
|
+ XML_ParserFree(parser);
|
|
+}
|
|
+END_TEST
|
|
+
|
|
+START_TEST(test_duplicate_cdata_attribute_multiple_attlistdecl_2) {
|
|
+ /*
|
|
+ https://www.w3.org/TR/xml/#attdecls
|
|
+
|
|
+ Test the following statement from the linked specification:
|
|
+ When more than one AttlistDecl is provided for a given element type,
|
|
+ the contents of all those provided are merged.
|
|
+ */
|
|
+ const char *text = "<!DOCTYPE doc [\n"
|
|
+ " <!ATTLIST doc attribute CDATA 'expected_doc'>\n"
|
|
+ " <!ATTLIST tag attribute CDATA 'expected_tag'>\n"
|
|
+ " <!ATTLIST doc attribute CDATA 'ignored_doc'>\n"
|
|
+ "]>\n"
|
|
+ "<doc><tag></tag></doc>\n";
|
|
+ AttrInfo doc_info[] = {{XCS("attribute"), XCS("expected_doc")}, {NULL, NULL}};
|
|
+ AttrInfo tag_info[] = {{XCS("attribute"), XCS("expected_tag")}, {NULL, NULL}};
|
|
+ ElementInfo info[] = {{XCS("doc"), 0, 1, NULL, doc_info},
|
|
+ {XCS("tag"), 0, 1, NULL, tag_info},
|
|
+ {NULL, 0, 0, NULL, NULL}};
|
|
+
|
|
+ XML_Parser parser = XML_ParserCreate(NULL);
|
|
+ assert_true(parser != NULL);
|
|
+
|
|
+ ParserAndElementInfo parserAndElementInfos = {
|
|
+ parser,
|
|
+ info,
|
|
+ };
|
|
+
|
|
+ XML_SetStartElementHandler(parser, counting_start_element_handler);
|
|
+ XML_SetUserData(parser, &parserAndElementInfos);
|
|
+
|
|
+ if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE)
|
|
+ != XML_STATUS_OK)
|
|
+ xml_failure(parser);
|
|
+
|
|
+ XML_ParserFree(parser);
|
|
+}
|
|
+END_TEST
|
|
+
|
|
+START_TEST(test_duplicate_cdata_attribute_multiple_attlistdecl_3) {
|
|
+ /*
|
|
+ https://www.w3.org/TR/xml/#attdecls
|
|
+
|
|
+ Test the following statement from the linked specification:
|
|
+ When more than one AttlistDecl is provided for a given element type,
|
|
+ the contents of all those provided are merged.
|
|
+ */
|
|
+ const char *text
|
|
+ = "<!DOCTYPE doc [\n"
|
|
+ " <!ATTLIST doc attribute CDATA 'expected_doc'>\n"
|
|
+ " <!ATTLIST tag attribute CDATA 'expected_tag'>\n"
|
|
+ " <!ATTLIST doc second_attribute CDATA 'second_expected_doc' attribute CDATA 'ignored_doc'>\n"
|
|
+ "]>\n"
|
|
+ "<doc><tag></tag></doc>\n";
|
|
+ AttrInfo doc_info[] = {{XCS("attribute"), XCS("expected_doc")},
|
|
+ {XCS("second_attribute"), XCS("second_expected_doc")},
|
|
+ {NULL, NULL}};
|
|
+ AttrInfo tag_info[] = {{XCS("attribute"), XCS("expected_tag")}, {NULL, NULL}};
|
|
+ ElementInfo info[] = {{XCS("doc"), 0, 2, NULL, doc_info},
|
|
+ {XCS("tag"), 0, 1, NULL, tag_info},
|
|
+ {NULL, 0, 0, NULL, NULL}};
|
|
+
|
|
+ XML_Parser parser = XML_ParserCreate(NULL);
|
|
+ assert_true(parser != NULL);
|
|
+
|
|
+ ParserAndElementInfo parserAndElementInfos = {
|
|
+ parser,
|
|
+ info,
|
|
+ };
|
|
+
|
|
+ XML_SetStartElementHandler(parser, counting_start_element_handler);
|
|
+ XML_SetUserData(parser, &parserAndElementInfos);
|
|
+
|
|
+ if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE)
|
|
+ != XML_STATUS_OK)
|
|
+ xml_failure(parser);
|
|
+
|
|
+ XML_ParserFree(parser);
|
|
+}
|
|
+END_TEST
|
|
+
|
|
+START_TEST(test_duplicate_id_attribute_multiple_attlistdecl) {
|
|
+ /*
|
|
+ https://www.w3.org/TR/xml/#attdecls
|
|
+
|
|
+ Test the following statement from the linked specification:
|
|
+ When more than one AttlistDecl is provided for a given element type,
|
|
+ the contents of all those provided are merged.
|
|
+ */
|
|
+ const char *text = "<!DOCTYPE doc [\n"
|
|
+ " <!ATTLIST doc identifier ID #REQUIRED>\n"
|
|
+ " <!ATTLIST tag identifier CDATA 'identifier_tag'>\n"
|
|
+ " <!ATTLIST doc identifier CDATA 'ignored'>\n"
|
|
+ "]>\n"
|
|
+ "<doc identifier='doc_identity'><tag></tag></doc>\n";
|
|
+ AttrInfo doc_info[]
|
|
+ = {{XCS("identifier"), XCS("doc_identity")}, {NULL, NULL}};
|
|
+ AttrInfo tag_info[]
|
|
+ = {{XCS("identifier"), XCS("identifier_tag")}, {NULL, NULL}};
|
|
+ ElementInfo info[] = {{XCS("doc"), 1, 0, XCS("identifier"), doc_info},
|
|
+ {XCS("tag"), 0, 1, NULL, tag_info},
|
|
+ {NULL, 0, 0, NULL, NULL}};
|
|
+
|
|
+ XML_Parser parser = XML_ParserCreate(NULL);
|
|
+ assert_true(parser != NULL);
|
|
+
|
|
+ ParserAndElementInfo parserAndElementInfos = {
|
|
+ parser,
|
|
+ info,
|
|
+ };
|
|
+
|
|
+ XML_SetStartElementHandler(parser, counting_start_element_handler);
|
|
+ XML_SetUserData(parser, &parserAndElementInfos);
|
|
+
|
|
+ if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE)
|
|
+ != XML_STATUS_OK)
|
|
+ xml_failure(parser);
|
|
+
|
|
+ XML_ParserFree(parser);
|
|
+}
|
|
+END_TEST
|
|
+
|
|
/* Test reset works correctly in the middle of processing an internal
|
|
* entity. Exercises some obscure code in XML_ParserReset().
|
|
*/
|
|
@@ -6325,6 +6598,15 @@ make_basic_test_case(Suite *s) {
|
|
tcase_add_test__ifdef_xml_dtd(tc_basic, test_empty_foreign_dtd);
|
|
tcase_add_test(tc_basic, test_set_base);
|
|
tcase_add_test(tc_basic, test_attributes);
|
|
+ tcase_add_test(tc_basic, test_duplicate_cdata_attribute);
|
|
+ tcase_add_test(tc_basic, test_duplicate_id_attribute_1);
|
|
+ tcase_add_test(tc_basic, test_duplicate_id_attribute_2);
|
|
+ tcase_add_test(tc_basic, test_duplicate_cdata_attribute_multiple_attlistdecl);
|
|
+ tcase_add_test(tc_basic,
|
|
+ test_duplicate_cdata_attribute_multiple_attlistdecl_2);
|
|
+ tcase_add_test(tc_basic,
|
|
+ test_duplicate_cdata_attribute_multiple_attlistdecl_3);
|
|
+ tcase_add_test(tc_basic, test_duplicate_id_attribute_multiple_attlistdecl);
|
|
tcase_add_test__if_xml_ge(tc_basic, test_reset_in_entity);
|
|
tcase_add_test(tc_basic, test_resume_invalid_parse);
|
|
tcase_add_test(tc_basic, test_resume_resuspended);
|
|
--
|
|
2.43.0
|
|
|