expat update to 2.5.0

This commit is contained in:
zhoupengcheng11 2023-01-31 12:01:01 +08:00
parent 4fdd8e02c2
commit 3ce9b8e218
7 changed files with 5 additions and 269 deletions

View File

@ -1,52 +0,0 @@
From 4a32da87e931ba54393d465bb77c40b5c33d343b Mon Sep 17 00:00:00 2001
From: Rhodri James <rhodri@wildebeest.org.uk>
Date: Wed, 17 Aug 2022 18:26:18 +0100
Subject: [PATCH] Ensure raw tagnames are safe exiting internalEntityParser
It is possible to concoct a situation in which parsing is
suspended while substituting in an internal entity, so that
XML_ResumeParser directly uses internalEntityProcessor as
its processor. If the subsequent parse includes some unclosed
tags, this will return without calling storeRawNames to ensure
that the raw versions of the tag names are stored in memory other
than the parse buffer itself. If the parse buffer is then changed
or reallocated (for example if processing a file line by line),
badness will ensue.
This patch ensures storeRawNames is always called when needed
after calling doContent. The earlier call do doContent does
not need the same protection; it only deals with entity
substitution, which cannot leave unbalanced tags, and in any
case the raw names will be pointing into the stored entity
value not the parse buffer.
---
lib/xmlparse.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/lib/xmlparse.c b/lib/xmlparse.c
index 7bcabf7f..d73f419c 100644
--- a/lib/xmlparse.c
+++ b/lib/xmlparse.c
@@ -5826,10 +5826,15 @@ internalEntityProcessor(XML_Parser parser, const char *s, const char *end,
{
parser->m_processor = contentProcessor;
/* see externalEntityContentProcessor vs contentProcessor */
- return doContent(parser, parser->m_parentParser ? 1 : 0, parser->m_encoding,
- s, end, nextPtr,
- (XML_Bool)! parser->m_parsingStatus.finalBuffer,
- XML_ACCOUNT_DIRECT);
+ result = doContent(parser, parser->m_parentParser ? 1 : 0,
+ parser->m_encoding, s, end, nextPtr,
+ (XML_Bool)! parser->m_parsingStatus.finalBuffer,
+ XML_ACCOUNT_DIRECT);
+ if (result == XML_ERROR_NONE) {
+ if (! storeRawNames(parser))
+ return XML_ERROR_NO_MEMORY;
+ }
+ return result;
}
}
--
2.27.0

View File

@ -1,104 +0,0 @@
From a7ce80a013f2a08cb1ac4aac368f2250eea03ebf Mon Sep 17 00:00:00 2001
From: Sebastian Pipping <sebastian@pipping.org>
Date: Sun, 11 Sep 2022 19:34:33 +0200
Subject: [PATCH] tests: Cover heap use-after-free issue in doContent
---
tests/runtests.c | 74 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 74 insertions(+)
diff --git a/tests/runtests.c b/tests/runtests.c
index ea371b42..ab3aff65 100644
--- a/tests/runtests.c
+++ b/tests/runtests.c
@@ -4990,6 +4990,78 @@ START_TEST(test_suspend_resume_internal_entity) {
}
END_TEST
+void
+suspending_comment_handler(void *userData, const XML_Char *data) {
+ UNUSED_P(data);
+ XML_Parser parser = (XML_Parser)userData;
+ XML_StopParser(parser, XML_TRUE);
+}
+
+START_TEST(test_suspend_resume_internal_entity_issue_629) {
+ const char *const text
+ = "<!DOCTYPE a [<!ENTITY e '<!--COMMENT-->a'>]><a>&e;<b>\n"
+ "<"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "/>"
+ "</b></a>";
+ const size_t firstChunkSizeBytes = 54;
+
+ XML_Parser parser = XML_ParserCreate(NULL);
+ XML_SetUserData(parser, parser);
+ XML_SetCommentHandler(parser, suspending_comment_handler);
+
+ if (XML_Parse(parser, text, (int)firstChunkSizeBytes, XML_FALSE)
+ != XML_STATUS_SUSPENDED)
+ xml_failure(parser);
+ if (XML_ResumeParser(parser) != XML_STATUS_OK)
+ xml_failure(parser);
+ if (XML_Parse(parser, text + firstChunkSizeBytes,
+ (int)(strlen(text) - firstChunkSizeBytes), XML_TRUE)
+ != XML_STATUS_OK)
+ xml_failure(parser);
+ XML_ParserFree(parser);
+}
+END_TEST
+
/* Test syntax error is caught at parse resumption */
START_TEST(test_resume_entity_with_syntax_error) {
const char *text = "<!DOCTYPE doc [\n"
@@ -12016,6 +12088,8 @@ make_suite(void) {
tcase_add_test(tc_basic, test_partial_char_in_epilog);
tcase_add_test(tc_basic, test_hash_collision);
tcase_add_test__ifdef_xml_dtd(tc_basic, test_suspend_resume_internal_entity);
+ tcase_add_test__ifdef_xml_dtd(tc_basic,
+ test_suspend_resume_internal_entity_issue_629);
tcase_add_test__ifdef_xml_dtd(tc_basic, test_resume_entity_with_syntax_error);
tcase_add_test__ifdef_xml_dtd(tc_basic, test_suspend_resume_parameter_entity);
tcase_add_test(tc_basic, test_restart_on_error);
--
2.27.0

View File

@ -1,29 +0,0 @@
From 5290462a7ea1278a8d5c0d5b2860d4e244f997e4 Mon Sep 17 00:00:00 2001
From: Sebastian Pipping <sebastian@pipping.org>
Date: Tue, 20 Sep 2022 02:44:34 +0200
Subject: [PATCH] lib: Fix overeager DTD destruction in
XML_ExternalEntityParserCreate
---
lib/xmlparse.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/lib/xmlparse.c b/lib/xmlparse.c
index aacd6e7fc..57bf103cc 100644
--- a/lib/xmlparse.c
+++ b/lib/xmlparse.c
@@ -1068,6 +1068,14 @@ parserCreate(const XML_Char *encodingName,
parserInit(parser, encodingName);
if (encodingName && ! parser->m_protocolEncodingName) {
+ if (dtd) {
+ // We need to stop the upcoming call to XML_ParserFree from happily
+ // destroying parser->m_dtd because the DTD is shared with the parent
+ // parser and the only guard that keeps XML_ParserFree from destroying
+ // parser->m_dtd is parser->m_isParamEntity but it will be set to
+ // XML_TRUE only later in XML_ExternalEntityParserCreate (or not at all).
+ parser->m_dtd = NULL;
+ }
XML_ParserFree(parser);
return NULL;
}

View File

@ -1,77 +0,0 @@
From 43992e4ae25fc3dc0eec0cd3a29313555d56aee2 Mon Sep 17 00:00:00 2001
From: Sebastian Pipping <sebastian@pipping.org>
Date: Mon, 19 Sep 2022 18:16:15 +0200
Subject: [PATCH] tests: Cover overeager DTD destruction in
XML_ExternalEntityParserCreate
---
tests/runtests.c | 49 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 49 insertions(+)
diff --git a/tests/runtests.c b/tests/runtests.c
index 245fe9bda..acb744dd4 100644
--- a/tests/runtests.c
+++ b/tests/runtests.c
@@ -10208,6 +10208,53 @@ START_TEST(test_alloc_long_notation) {
}
END_TEST
+static int XMLCALL
+external_entity_parser_create_alloc_fail_handler(XML_Parser parser,
+ const XML_Char *context,
+ const XML_Char *base,
+ const XML_Char *systemId,
+ const XML_Char *publicId) {
+ UNUSED_P(base);
+ UNUSED_P(systemId);
+ UNUSED_P(publicId);
+
+ if (context != NULL)
+ fail("Unexpected non-NULL context");
+
+ // The following number intends to fail the upcoming allocation in line
+ // "parser->m_protocolEncodingName = copyString(encodingName,
+ // &(parser->m_mem));" in function parserInit.
+ allocation_count = 3;
+
+ const XML_Char *const encodingName = XCS("UTF-8"); // needs something non-NULL
+ const XML_Parser ext_parser
+ = XML_ExternalEntityParserCreate(parser, context, encodingName);
+ if (ext_parser != NULL)
+ fail(
+ "Call to XML_ExternalEntityParserCreate was expected to fail out-of-memory");
+
+ allocation_count = ALLOC_ALWAYS_SUCCEED;
+ return XML_STATUS_ERROR;
+}
+
+START_TEST(test_alloc_reset_after_external_entity_parser_create_fail) {
+ const char *const text = "<!DOCTYPE doc SYSTEM 'foo'><doc/>";
+
+ XML_SetExternalEntityRefHandler(
+ g_parser, external_entity_parser_create_alloc_fail_handler);
+ XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
+
+ if (XML_Parse(g_parser, text, (int)strlen(text), XML_TRUE)
+ != XML_STATUS_ERROR)
+ fail("Call to parse was expected to fail");
+
+ if (XML_GetErrorCode(g_parser) != XML_ERROR_EXTERNAL_ENTITY_HANDLING)
+ fail("Call to parse was expected to fail from the external entity handler");
+
+ XML_ParserReset(g_parser, NULL);
+}
+END_TEST
+
static void
nsalloc_setup(void) {
XML_Memory_Handling_Suite memsuite = {duff_allocator, duff_reallocator, free};
@@ -12401,6 +12448,8 @@ make_suite(void) {
tcase_add_test(tc_alloc, test_alloc_long_public_id);
tcase_add_test(tc_alloc, test_alloc_long_entity_value);
tcase_add_test(tc_alloc, test_alloc_long_notation);
+ tcase_add_test__ifdef_xml_dtd(
+ tc_alloc, test_alloc_reset_after_external_entity_parser_create_fail);
suite_add_tcase(s, tc_nsalloc);
tcase_add_checked_fixture(tc_nsalloc, nsalloc_setup, nsalloc_teardown);

Binary file not shown.

BIN
expat-2.5.0.tar.gz Normal file

Binary file not shown.

View File

@ -1,17 +1,12 @@
%define Rversion %(echo %{version} | sed -e 's/\\./_/g' -e 's/^/R_/')
Name: expat
Version: 2.4.8
Release: 5
Version: 2.5.0
Release: 1
Summary: An XML parser library
License: MIT
URL: https://libexpat.github.io/
Source0: https://github.com/libexpat/libexpat/releases/download/%{Rversion}/expat-%{version}.tar.gz
Patch0: backport-0001-CVE-2022-40674.patch
Patch1: backport-0002-CVE-2022-40674.patch
Patch2: backport-CVE-2022-43680.patch
Patch3: backport-tests-Cover-overeager-DTD-destruction-in-XML_Externa.patch
BuildRequires: sed,autoconf,automake,gcc-c++,libtool,xmlto
%description
@ -64,6 +59,9 @@ make check
%{_mandir}/man1/*
%changelog
* Tue Jan 31 2023 zhoupengcheng <zhoupengcheng11@huawei.com> - 2.5.0-1
- expat update to 2.5.0
* Tue Dec 13 2022 zhoupengcheng <zhoupengcheng11@huawei.com> - 2.4.8-5
- Move autoreconf to build