Compare commits
No commits in common. "c8" and "c9s-plans-gating-update" have entirely different histories.
c8
...
c9s-plans-
@ -1 +0,0 @@
|
||||
03d9882ede56aa48919fbf50fe17614630257a82 SOURCES/expat-2.5.0.tar.gz
|
||||
1
.fmf/version
Normal file
1
.fmf/version
Normal file
@ -0,0 +1 @@
|
||||
1
|
||||
24
.gitignore
vendored
24
.gitignore
vendored
@ -1 +1,23 @@
|
||||
SOURCES/expat-2.5.0.tar.gz
|
||||
expat-1.95.8.tar.gz
|
||||
i386
|
||||
*.rpm
|
||||
clog
|
||||
expat-2.0.1.tar.gz
|
||||
/results_expat
|
||||
/expat-2.?.?
|
||||
/expat-2.1.0.tar.gz
|
||||
/expat-2.1.1.tar.bz2
|
||||
/expat-2.2.0.tar.bz2
|
||||
/expat-2.2.1.tar.gz
|
||||
/expat-2.2.2.tar.gz
|
||||
/libexpat-R_*
|
||||
/expat-2.2.3.tar.gz
|
||||
/expat-2.2.4.tar.gz
|
||||
/expat-2.2.5.tar.gz
|
||||
/expat-2.2.6.tar.gz
|
||||
/expat-2.2.7.tar.gz
|
||||
/expat-2.2.8.tar.gz
|
||||
/expat-2.2.10.tar.gz
|
||||
/expat-2.4.7.tar.gz
|
||||
/expat-2.4.9.tar.gz
|
||||
/expat-2.5.0.tar.gz
|
||||
|
||||
@ -1,129 +0,0 @@
|
||||
commit 05d87eb116ddde35bfa4e4c1d2ec7bcbda38c09b
|
||||
Author: Tomas Korbar <tkorbar@redhat.com>
|
||||
Date: Wed Sep 11 13:48:58 2024 +0200
|
||||
|
||||
Fix CVE-2024-45490
|
||||
|
||||
https://github.com/libexpat/libexpat/pull/890
|
||||
|
||||
diff --git a/expat/doc/reference.html b/expat/doc/reference.html
|
||||
index a10f3cb..d618bd8 100644
|
||||
--- a/expat/doc/reference.html
|
||||
+++ b/expat/doc/reference.html
|
||||
@@ -1098,7 +1098,9 @@ containing part (or perhaps all) of the document. The number of bytes of s
|
||||
that are part of the document is indicated by <code>len</code>. This means
|
||||
that <code>s</code> doesn't have to be null terminated. It also means that
|
||||
if <code>len</code> is larger than the number of bytes in the block of
|
||||
-memory that <code>s</code> points at, then a memory fault is likely. The
|
||||
+memory that <code>s</code> points at, then a memory fault is likely.
|
||||
+Negative values for <code>len</code> are rejected since Expat 2.2.1.
|
||||
+The
|
||||
<code>isFinal</code> parameter informs the parser that this is the last
|
||||
piece of the document. Frequently, the last piece is empty (i.e.
|
||||
<code>len</code> is zero.)
|
||||
@@ -1114,11 +1116,17 @@ XML_ParseBuffer(XML_Parser p,
|
||||
int isFinal);
|
||||
</pre>
|
||||
<div class="fcndef">
|
||||
+<p>
|
||||
This is just like <code><a href= "#XML_Parse" >XML_Parse</a></code>,
|
||||
except in this case Expat provides the buffer. By obtaining the
|
||||
buffer from Expat with the <code><a href= "#XML_GetBuffer"
|
||||
>XML_GetBuffer</a></code> function, the application can avoid double
|
||||
copying of the input.
|
||||
+</p>
|
||||
+
|
||||
+<p>
|
||||
+Negative values for <code>len</code> are rejected since Expat 2.6.3.
|
||||
+</p>
|
||||
</div>
|
||||
|
||||
<h4 id="XML_GetBuffer">XML_GetBuffer</h4>
|
||||
diff --git a/expat/lib/xmlparse.c b/expat/lib/xmlparse.c
|
||||
index 0896b16..f54e258 100644
|
||||
--- a/expat/lib/xmlparse.c
|
||||
+++ b/expat/lib/xmlparse.c
|
||||
@@ -1998,6 +1998,12 @@ XML_ParseBuffer(XML_Parser parser, int len, int isFinal) {
|
||||
|
||||
if (parser == NULL)
|
||||
return XML_STATUS_ERROR;
|
||||
+
|
||||
+ if (len < 0) {
|
||||
+ parser->m_errorCode = XML_ERROR_INVALID_ARGUMENT;
|
||||
+ return XML_STATUS_ERROR;
|
||||
+ }
|
||||
+
|
||||
switch (parser->m_parsingStatus.parsing) {
|
||||
case XML_SUSPENDED:
|
||||
parser->m_errorCode = XML_ERROR_SUSPENDED;
|
||||
diff --git a/expat/tests/runtests.c b/expat/tests/runtests.c
|
||||
index 93adc45..ed88f9f 100644
|
||||
--- a/expat/tests/runtests.c
|
||||
+++ b/expat/tests/runtests.c
|
||||
@@ -3856,6 +3856,57 @@ START_TEST(test_empty_parse) {
|
||||
}
|
||||
END_TEST
|
||||
|
||||
+/* Test XML_Parse for len < 0 */
|
||||
+START_TEST(test_negative_len_parse) {
|
||||
+ const char *const doc = "<root/>";
|
||||
+ for (int isFinal = 0; isFinal < 2; isFinal++) {
|
||||
+ XML_Parser parser = XML_ParserCreate(NULL);
|
||||
+
|
||||
+ if (XML_GetErrorCode(parser) != XML_ERROR_NONE)
|
||||
+ fail("There was not supposed to be any initial parse error.");
|
||||
+
|
||||
+ const enum XML_Status status = XML_Parse(parser, doc, -1, isFinal);
|
||||
+
|
||||
+ if (status != XML_STATUS_ERROR)
|
||||
+ fail("Negative len was expected to fail the parse but did not.");
|
||||
+
|
||||
+ if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_ARGUMENT)
|
||||
+ fail("Parse error does not match XML_ERROR_INVALID_ARGUMENT.");
|
||||
+
|
||||
+ XML_ParserFree(parser);
|
||||
+ }
|
||||
+}
|
||||
+END_TEST
|
||||
+
|
||||
+/* Test XML_ParseBuffer for len < 0 */
|
||||
+START_TEST(test_negative_len_parse_buffer) {
|
||||
+ const char *const doc = "<root/>";
|
||||
+ for (int isFinal = 0; isFinal < 2; isFinal++) {
|
||||
+ XML_Parser parser = XML_ParserCreate(NULL);
|
||||
+
|
||||
+ if (XML_GetErrorCode(parser) != XML_ERROR_NONE)
|
||||
+ fail("There was not supposed to be any initial parse error.");
|
||||
+
|
||||
+ void *const buffer = XML_GetBuffer(parser, (int)strlen(doc));
|
||||
+
|
||||
+ if (buffer == NULL)
|
||||
+ fail("XML_GetBuffer failed.");
|
||||
+
|
||||
+ memcpy(buffer, doc, strlen(doc));
|
||||
+
|
||||
+ const enum XML_Status status = XML_ParseBuffer(parser, -1, isFinal);
|
||||
+
|
||||
+ if (status != XML_STATUS_ERROR)
|
||||
+ fail("Negative len was expected to fail the parse but did not.");
|
||||
+
|
||||
+ if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_ARGUMENT)
|
||||
+ fail("Parse error does not match XML_ERROR_INVALID_ARGUMENT.");
|
||||
+
|
||||
+ XML_ParserFree(parser);
|
||||
+ }
|
||||
+}
|
||||
+END_TEST
|
||||
+
|
||||
/* Test odd corners of the XML_GetBuffer interface */
|
||||
static enum XML_Status
|
||||
get_feature(enum XML_FeatureEnum feature_id, long *presult) {
|
||||
@@ -12937,6 +12988,8 @@ make_suite(void) {
|
||||
tcase_add_test__ifdef_xml_dtd(tc_basic, test_user_parameters);
|
||||
tcase_add_test__ifdef_xml_dtd(tc_basic, test_ext_entity_ref_parameter);
|
||||
tcase_add_test(tc_basic, test_empty_parse);
|
||||
+ tcase_add_test(tc_basic, test_negative_len_parse);
|
||||
+ tcase_add_test(tc_basic, test_negative_len_parse_buffer);
|
||||
tcase_add_test(tc_basic, test_get_buffer_1);
|
||||
tcase_add_test(tc_basic, test_get_buffer_2);
|
||||
#if defined(XML_CONTEXT_BYTES)
|
||||
@ -1,31 +0,0 @@
|
||||
From 8e439a9947e9dc80a395c0c7456545d8d9d9e421 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Pipping <sebastian@pipping.org>
|
||||
Date: Mon, 19 Aug 2024 22:34:13 +0200
|
||||
Subject: [PATCH] lib: Detect integer overflow in dtdCopy
|
||||
|
||||
Reported by TaiYou
|
||||
---
|
||||
expat/lib/xmlparse.c | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
diff --git a/expat/lib/xmlparse.c b/expat/lib/xmlparse.c
|
||||
index 91682c188..e2327bdcf 100644
|
||||
--- a/expat/lib/xmlparse.c
|
||||
+++ b/expat/lib/xmlparse.c
|
||||
@@ -7016,6 +7016,16 @@ dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd,
|
||||
if (! newE)
|
||||
return 0;
|
||||
if (oldE->nDefaultAtts) {
|
||||
+ /* Detect and prevent integer overflow.
|
||||
+ * The preprocessor guard addresses the "always false" warning
|
||||
+ * from -Wtype-limits on platforms where
|
||||
+ * sizeof(int) < sizeof(size_t), e.g. on x86_64. */
|
||||
+#if UINT_MAX >= SIZE_MAX
|
||||
+ if ((size_t)oldE->nDefaultAtts
|
||||
+ > ((size_t)(-1) / sizeof(DEFAULT_ATTRIBUTE))) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+#endif
|
||||
newE->defaultAtts
|
||||
= ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
|
||||
if (! newE->defaultAtts) {
|
||||
@ -1,30 +0,0 @@
|
||||
From 9bf0f2c16ee86f644dd1432507edff94c08dc232 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Pipping <sebastian@pipping.org>
|
||||
Date: Mon, 19 Aug 2024 22:37:16 +0200
|
||||
Subject: [PATCH] lib: Detect integer overflow in function nextScaffoldPart
|
||||
|
||||
Reported by TaiYou
|
||||
---
|
||||
expat/lib/xmlparse.c | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
diff --git a/expat/lib/xmlparse.c b/expat/lib/xmlparse.c
|
||||
index 91682c188..f737575ea 100644
|
||||
--- a/expat/lib/xmlparse.c
|
||||
+++ b/expat/lib/xmlparse.c
|
||||
@@ -7558,6 +7558,15 @@ nextScaffoldPart(XML_Parser parser) {
|
||||
int next;
|
||||
|
||||
if (! dtd->scaffIndex) {
|
||||
+ /* Detect and prevent integer overflow.
|
||||
+ * The preprocessor guard addresses the "always false" warning
|
||||
+ * from -Wtype-limits on platforms where
|
||||
+ * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
|
||||
+#if UINT_MAX >= SIZE_MAX
|
||||
+ if (parser->m_groupSize > ((size_t)(-1) / sizeof(int))) {
|
||||
+ return -1;
|
||||
+ }
|
||||
+#endif
|
||||
dtd->scaffIndex = (int *)MALLOC(parser, parser->m_groupSize * sizeof(int));
|
||||
if (! dtd->scaffIndex)
|
||||
return -1;
|
||||
@ -1,108 +0,0 @@
|
||||
commit 38905b99bb78a6a691ed8358f30030116783656c
|
||||
Author: Tomas Korbar <tkorbar@redhat.com>
|
||||
Date: Thu Nov 7 15:00:46 2024 +0100
|
||||
|
||||
Fix CVE-2024-50602
|
||||
|
||||
See https://github.com/libexpat/libexpat/pull/915
|
||||
|
||||
diff --git a/expat/lib/expat.h b/expat/lib/expat.h
|
||||
index 842dd70..69b0ba1 100644
|
||||
--- a/expat/lib/expat.h
|
||||
+++ b/expat/lib/expat.h
|
||||
@@ -128,7 +128,9 @@ enum XML_Error {
|
||||
/* Added in 2.3.0. */
|
||||
XML_ERROR_NO_BUFFER,
|
||||
/* Added in 2.4.0. */
|
||||
- XML_ERROR_AMPLIFICATION_LIMIT_BREACH
|
||||
+ XML_ERROR_AMPLIFICATION_LIMIT_BREACH,
|
||||
+ /* Added in 2.6.4. */
|
||||
+ XML_ERROR_NOT_STARTED,
|
||||
};
|
||||
|
||||
enum XML_Content_Type {
|
||||
diff --git a/expat/lib/xmlparse.c b/expat/lib/xmlparse.c
|
||||
index e0c2873..8b2af91 100644
|
||||
--- a/expat/lib/xmlparse.c
|
||||
+++ b/expat/lib/xmlparse.c
|
||||
@@ -2193,6 +2193,9 @@ XML_StopParser(XML_Parser parser, XML_Bool resumable) {
|
||||
if (parser == NULL)
|
||||
return XML_STATUS_ERROR;
|
||||
switch (parser->m_parsingStatus.parsing) {
|
||||
+ case XML_INITIALIZED:
|
||||
+ parser->m_errorCode = XML_ERROR_NOT_STARTED;
|
||||
+ return XML_STATUS_ERROR;
|
||||
case XML_SUSPENDED:
|
||||
if (resumable) {
|
||||
parser->m_errorCode = XML_ERROR_SUSPENDED;
|
||||
@@ -2203,7 +2206,7 @@ XML_StopParser(XML_Parser parser, XML_Bool resumable) {
|
||||
case XML_FINISHED:
|
||||
parser->m_errorCode = XML_ERROR_FINISHED;
|
||||
return XML_STATUS_ERROR;
|
||||
- default:
|
||||
+ case XML_PARSING:
|
||||
if (resumable) {
|
||||
#ifdef XML_DTD
|
||||
if (parser->m_isParamEntity) {
|
||||
@@ -2214,6 +2217,9 @@ XML_StopParser(XML_Parser parser, XML_Bool resumable) {
|
||||
parser->m_parsingStatus.parsing = XML_SUSPENDED;
|
||||
} else
|
||||
parser->m_parsingStatus.parsing = XML_FINISHED;
|
||||
+ break;
|
||||
+ default:
|
||||
+ assert(0);
|
||||
}
|
||||
return XML_STATUS_OK;
|
||||
}
|
||||
@@ -2478,6 +2484,9 @@ XML_ErrorString(enum XML_Error code) {
|
||||
case XML_ERROR_AMPLIFICATION_LIMIT_BREACH:
|
||||
return XML_L(
|
||||
"limit on input amplification factor (from DTD and entities) breached");
|
||||
+ /* Added in 2.6.4. */
|
||||
+ case XML_ERROR_NOT_STARTED:
|
||||
+ return XML_L("parser not started");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
diff --git a/expat/tests/runtests.c b/expat/tests/runtests.c
|
||||
index ed88f9f..5769aa0 100644
|
||||
--- a/expat/tests/runtests.c
|
||||
+++ b/expat/tests/runtests.c
|
||||
@@ -8711,6 +8711,28 @@ START_TEST(test_misc_tag_mismatch_reset_leak) {
|
||||
}
|
||||
END_TEST
|
||||
|
||||
+START_TEST(test_misc_resumeparser_not_crashing) {
|
||||
+ XML_Parser parser = XML_ParserCreate(NULL);
|
||||
+ XML_GetBuffer(parser, 1);
|
||||
+ XML_StopParser(parser, /*resumable=*/XML_TRUE);
|
||||
+ XML_ResumeParser(parser); // could crash here, previously
|
||||
+ XML_ParserFree(parser);
|
||||
+}
|
||||
+END_TEST
|
||||
+
|
||||
+START_TEST(test_misc_stopparser_rejects_unstarted_parser) {
|
||||
+ const XML_Bool cases[] = {XML_TRUE, XML_FALSE};
|
||||
+ for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) {
|
||||
+ const XML_Bool resumable = cases[i];
|
||||
+ XML_Parser parser = XML_ParserCreate(NULL);
|
||||
+ assert_true(XML_GetErrorCode(parser) == XML_ERROR_NONE);
|
||||
+ assert_true(XML_StopParser(parser, resumable) == XML_STATUS_ERROR);
|
||||
+ assert_true(XML_GetErrorCode(parser) == XML_ERROR_NOT_STARTED);
|
||||
+ XML_ParserFree(parser);
|
||||
+ }
|
||||
+}
|
||||
+END_TEST
|
||||
+
|
||||
static void
|
||||
alloc_setup(void) {
|
||||
XML_Memory_Handling_Suite memsuite = {duff_allocator, duff_reallocator, free};
|
||||
@@ -13176,6 +13198,8 @@ make_suite(void) {
|
||||
tcase_add_test__ifdef_xml_dtd(
|
||||
tc_misc, test_misc_deny_internal_entity_closing_doctype_issue_317);
|
||||
tcase_add_test(tc_misc, test_misc_tag_mismatch_reset_leak);
|
||||
+ tcase_add_test(tc_misc, test_misc_resumeparser_not_crashing);
|
||||
+ tcase_add_test(tc_misc, test_misc_stopparser_rejects_unstarted_parser);
|
||||
|
||||
suite_add_tcase(s, tc_alloc);
|
||||
tcase_add_checked_fixture(tc_alloc, alloc_setup, alloc_teardown);
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,635 +0,0 @@
|
||||
From 88e9daef8fdaea58da12044cd16f5c9c1f201bfa 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:26:45 +0100
|
||||
Subject: [PATCH 1/6] Make "counting_start_element_handler" count default attrs
|
||||
|
||||
---
|
||||
expat/tests/runtests.c | 11 ++++++-----
|
||||
1 file changed, 6 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/expat/tests/runtests.c b/expat/tests/runtests.c
|
||||
index 4a0a2e3f..c66656e0 100644
|
||||
--- a/expat/tests/runtests.c
|
||||
+++ b/expat/tests/runtests.c
|
||||
@@ -3045,6 +3045,7 @@ typedef struct attrInfo {
|
||||
typedef struct elementInfo {
|
||||
const XML_Char *name;
|
||||
int attr_count;
|
||||
+ int default_attr_count;
|
||||
const XML_Char *id_name;
|
||||
AttrInfo *attributes;
|
||||
} ElementInfo;
|
||||
@@ -3089,7 +3090,7 @@ counting_start_element_handler(void *userData, const XML_Char *name,
|
||||
fail("ID does not have the correct name");
|
||||
return;
|
||||
}
|
||||
- for (i = 0; i < info->attr_count; i++) {
|
||||
+ for (i = 0; i < info->attr_count + info->default_attr_count; i++) {
|
||||
attr = info->attributes;
|
||||
while (attr->name != NULL) {
|
||||
if (! xcstrcmp(atts[0], attr->name))
|
||||
@@ -3122,9 +3123,9 @@ START_TEST(test_attributes) {
|
||||
{XCS("id"), XCS("one")},
|
||||
{NULL, NULL}};
|
||||
AttrInfo tag_info[] = {{XCS("c"), XCS("3")}, {NULL, NULL}};
|
||||
- ElementInfo info[] = {{XCS("doc"), 3, XCS("id"), NULL},
|
||||
- {XCS("tag"), 1, NULL, NULL},
|
||||
- {NULL, 0, NULL, NULL}};
|
||||
+ ElementInfo info[] = {{XCS("doc"), 3, 0, XCS("id"), NULL},
|
||||
+ {XCS("tag"), 1, 0, NULL, NULL},
|
||||
+ {NULL, 0, 0, NULL, NULL}};
|
||||
info[0].attributes = doc_info;
|
||||
info[1].attributes = tag_info;
|
||||
|
||||
@@ -7111,7 +7112,7 @@ START_TEST(test_deep_nested_attribute_entity) {
|
||||
(long unsigned)(N_LINES - 1));
|
||||
|
||||
AttrInfo doc_info[] = {{XCS("name"), XCS("deepText")}, {NULL, NULL}};
|
||||
- ElementInfo info[] = {{XCS("foo"), 1, NULL, NULL}, {NULL, 0, NULL, NULL}};
|
||||
+ ElementInfo info[] = {{XCS("foo"), 1, 0, NULL, NULL}, {NULL, 0, 0, NULL, NULL}};
|
||||
info[0].attributes = doc_info;
|
||||
|
||||
XML_SetStartElementHandler(g_parser, counting_start_element_handler);
|
||||
--
|
||||
2.52.0
|
||||
|
||||
|
||||
From 04796d5b0e71cc37a4bfa0031270d7bee6e0128a 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/6] test(attlist): Cover duplicate attribute names
|
||||
|
||||
Co-authored-by: Sebastian Pipping <sebastian@pipping.org>
|
||||
---
|
||||
expat/tests/runtests.c | 315 +++++++++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 302 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/expat/tests/runtests.c b/expat/tests/runtests.c
|
||||
index c66656e0..13583e0a 100644
|
||||
--- a/expat/tests/runtests.c
|
||||
+++ b/expat/tests/runtests.c
|
||||
@@ -3059,7 +3059,9 @@ typedef struct StructParserAndElementInfo {
|
||||
static void XMLCALL
|
||||
counting_start_element_handler(void *userData, const XML_Char *name,
|
||||
const XML_Char **atts) {
|
||||
- ElementInfo *info = (ElementInfo *)userData;
|
||||
+ ParserAndElementInfo *const parserAndElementInfos
|
||||
+ = (ParserAndElementInfo *)userData;
|
||||
+ ElementInfo *info = parserAndElementInfos->info;
|
||||
AttrInfo *attr;
|
||||
int count, id, i;
|
||||
|
||||
@@ -3076,17 +3078,17 @@ counting_start_element_handler(void *userData, const XML_Char *name,
|
||||
* is possibly a little unexpected, but it is what the
|
||||
* documentation in expat.h tells us to expect.
|
||||
*/
|
||||
- count = XML_GetSpecifiedAttributeCount(g_parser);
|
||||
+ count = XML_GetSpecifiedAttributeCount(parserAndElementInfos->parser);
|
||||
if (info->attr_count * 2 != count) {
|
||||
fail("Not got expected attribute count");
|
||||
return;
|
||||
}
|
||||
- id = XML_GetIdAttributeIndex(g_parser);
|
||||
+ id = XML_GetIdAttributeIndex(parserAndElementInfos->parser);
|
||||
if (id == -1 && info->id_name != NULL) {
|
||||
fail("ID not present");
|
||||
return;
|
||||
}
|
||||
- if (id != -1 && xcstrcmp(atts[id], info->id_name)) {
|
||||
+ if (id != -1 && xcstrcmp(atts[id], info->id_name) != 0) {
|
||||
fail("ID does not have the correct name");
|
||||
return;
|
||||
}
|
||||
@@ -3101,7 +3103,7 @@ counting_start_element_handler(void *userData, const XML_Char *name,
|
||||
fail("Attribute not recognised");
|
||||
return;
|
||||
}
|
||||
- if (xcstrcmp(atts[1], attr->value)) {
|
||||
+ if (xcstrcmp(atts[1], attr->value) != 0) {
|
||||
fail("Attribute has wrong value");
|
||||
return;
|
||||
}
|
||||
@@ -3123,20 +3125,296 @@ START_TEST(test_attributes) {
|
||||
{XCS("id"), XCS("one")},
|
||||
{NULL, NULL}};
|
||||
AttrInfo tag_info[] = {{XCS("c"), XCS("3")}, {NULL, NULL}};
|
||||
- ElementInfo info[] = {{XCS("doc"), 3, 0, XCS("id"), NULL},
|
||||
- {XCS("tag"), 1, 0, NULL, NULL},
|
||||
+ ElementInfo info[] = {{XCS("doc"), 3, 0, XCS("id"), doc_info},
|
||||
+ {XCS("tag"), 1, 0, NULL, tag_info},
|
||||
{NULL, 0, 0, NULL, NULL}};
|
||||
- info[0].attributes = doc_info;
|
||||
- info[1].attributes = tag_info;
|
||||
+
|
||||
+ ParserAndElementInfo parserAndElementInfos = {
|
||||
+ g_parser,
|
||||
+ info,
|
||||
+ };
|
||||
|
||||
XML_SetStartElementHandler(g_parser, counting_start_element_handler);
|
||||
- XML_SetUserData(g_parser, info);
|
||||
+ XML_SetUserData(g_parser, &parserAndElementInfos);
|
||||
if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
|
||||
== XML_STATUS_ERROR)
|
||||
xml_failure(g_parser);
|
||||
}
|
||||
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().
|
||||
*/
|
||||
@@ -7112,11 +7390,13 @@ START_TEST(test_deep_nested_attribute_entity) {
|
||||
(long unsigned)(N_LINES - 1));
|
||||
|
||||
AttrInfo doc_info[] = {{XCS("name"), XCS("deepText")}, {NULL, NULL}};
|
||||
- ElementInfo info[] = {{XCS("foo"), 1, 0, NULL, NULL}, {NULL, 0, 0, NULL, NULL}};
|
||||
- info[0].attributes = doc_info;
|
||||
+ ElementInfo info[]
|
||||
+ = {{XCS("foo"), 1, 0, NULL, doc_info}, {NULL, 0, 0, NULL, NULL}};
|
||||
+
|
||||
+ ParserAndElementInfo parserAndElementInfos = {g_parser, info};
|
||||
|
||||
XML_SetStartElementHandler(g_parser, counting_start_element_handler);
|
||||
- XML_SetUserData(g_parser, &info);
|
||||
+ XML_SetUserData(g_parser, &parserAndElementInfos);
|
||||
|
||||
if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
|
||||
== XML_STATUS_ERROR)
|
||||
@@ -13625,6 +13905,15 @@ make_suite(void) {
|
||||
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(tc_basic, test_reset_in_entity);
|
||||
tcase_add_test(tc_basic, test_resume_invalid_parse);
|
||||
tcase_add_test(tc_basic, test_resume_resuspended);
|
||||
--
|
||||
2.52.0
|
||||
|
||||
|
||||
From 58d4b742fd88c9789e4a5e68de02164145f9c593 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Pipping <sebastian@pipping.org>
|
||||
Date: Mon, 13 Apr 2026 01:34:03 +0200
|
||||
Subject: [PATCH 3/6] tests: Make counting_start_element_handler enforce
|
||||
complete attribute lists
|
||||
|
||||
---
|
||||
expat/tests/runtests.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/expat/tests/runtests.c b/expat/tests/runtests.c
|
||||
index 13583e0a..659ed030 100644
|
||||
--- a/expat/tests/runtests.c
|
||||
+++ b/expat/tests/runtests.c
|
||||
@@ -3110,6 +3110,9 @@ counting_start_element_handler(void *userData, const XML_Char *name,
|
||||
/* Remember, two entries in atts per attribute (see above) */
|
||||
atts += 2;
|
||||
}
|
||||
+
|
||||
+ // Self-test that the test case's list of expected attributes is complete
|
||||
+ assert_true(atts[0] == NULL);
|
||||
}
|
||||
|
||||
START_TEST(test_attributes) {
|
||||
--
|
||||
2.52.0
|
||||
|
||||
|
||||
From 2f13a612e82242af9954508240c6edfaf7cb0721 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Pipping <sebastian@pipping.org>
|
||||
Date: Sun, 8 Mar 2026 22:14:41 +0100
|
||||
Subject: [PATCH 4/6] lib: Extract a constant for upcoming reuse
|
||||
|
||||
---
|
||||
expat/lib/xmlparse.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/expat/lib/xmlparse.c b/expat/lib/xmlparse.c
|
||||
index cba41f4b..ac9512e9 100644
|
||||
--- a/expat/lib/xmlparse.c
|
||||
+++ b/expat/lib/xmlparse.c
|
||||
@@ -7528,8 +7528,9 @@ dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd,
|
||||
newE->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
|
||||
oldE->prefix->name, 0);
|
||||
for (i = 0; i < newE->nDefaultAtts; i++) {
|
||||
+ const XML_Char *const attributeName = oldE->defaultAtts[i].id->name;
|
||||
newE->defaultAtts[i].id = (ATTRIBUTE_ID *)lookup(
|
||||
- oldParser, &(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
|
||||
+ oldParser, &(newDtd->attributeIds), attributeName, 0);
|
||||
newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
|
||||
if (oldE->defaultAtts[i].value) {
|
||||
newE->defaultAtts[i].value
|
||||
--
|
||||
2.52.0
|
||||
|
||||
|
||||
From 8211c5affe00c6d92025f34ae7ffbc0f78426692 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Pipping <sebastian@pipping.org>
|
||||
Date: Sun, 8 Mar 2026 23:05:49 +0100
|
||||
Subject: [PATCH 5/6] lib: Introduce ELEMENT_TYPE.defaultAttsNames
|
||||
|
||||
---
|
||||
expat/lib/xmlparse.c | 17 +++++++++++++++++
|
||||
1 file changed, 17 insertions(+)
|
||||
|
||||
diff --git a/expat/lib/xmlparse.c b/expat/lib/xmlparse.c
|
||||
index ac9512e9..d8e7335d 100644
|
||||
--- a/expat/lib/xmlparse.c
|
||||
+++ b/expat/lib/xmlparse.c
|
||||
@@ -368,6 +368,7 @@ typedef struct {
|
||||
int nDefaultAtts;
|
||||
int allocDefaultAtts;
|
||||
DEFAULT_ATTRIBUTE *defaultAtts;
|
||||
+ HASH_TABLE defaultAttsNames;
|
||||
} ELEMENT_TYPE;
|
||||
|
||||
typedef struct {
|
||||
@@ -3756,6 +3757,8 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr,
|
||||
sizeof(ELEMENT_TYPE));
|
||||
if (! elementType)
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
+ if (! elementType->defaultAttsNames.parser)
|
||||
+ hashTableInit(&(elementType->defaultAttsNames), parser);
|
||||
if (parser->m_ns && ! setElementTypePrefix(parser, elementType))
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
}
|
||||
@@ -7369,6 +7372,7 @@ dtdReset(DTD *p, XML_Parser parser) {
|
||||
ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
|
||||
if (! e)
|
||||
break;
|
||||
+ hashTableDestroy(&(e->defaultAttsNames));
|
||||
if (e->allocDefaultAtts != 0)
|
||||
FREE(parser, e->defaultAtts);
|
||||
}
|
||||
@@ -7410,6 +7414,7 @@ dtdDestroy(DTD *p, XML_Bool isDocEntity, XML_Parser parser) {
|
||||
ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
|
||||
if (! e)
|
||||
break;
|
||||
+ hashTableDestroy(&(e->defaultAttsNames));
|
||||
if (e->allocDefaultAtts != 0)
|
||||
FREE(parser, e->defaultAtts);
|
||||
}
|
||||
@@ -7503,6 +7508,10 @@ dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd,
|
||||
sizeof(ELEMENT_TYPE));
|
||||
if (! newE)
|
||||
return 0;
|
||||
+
|
||||
+ if (! newE->defaultAttsNames.parser)
|
||||
+ hashTableInit(&(newE->defaultAttsNames), parser);
|
||||
+
|
||||
if (oldE->nDefaultAtts) {
|
||||
/* Detect and prevent integer overflow.
|
||||
* The preprocessor guard addresses the "always false" warning
|
||||
@@ -7539,6 +7548,12 @@ dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd,
|
||||
return 0;
|
||||
} else
|
||||
newE->defaultAtts[i].value = NULL;
|
||||
+
|
||||
+ NAMED *const nameAddedOrFound = (NAMED *)lookup(
|
||||
+ parser, &(newE->defaultAttsNames), attributeName, sizeof(NAMED));
|
||||
+ if (! nameAddedOrFound) {
|
||||
+ return 0;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8263,6 +8278,8 @@ getElementType(XML_Parser parser, const ENCODING *enc, const char *ptr,
|
||||
sizeof(ELEMENT_TYPE));
|
||||
if (! ret)
|
||||
return NULL;
|
||||
+ if (! ret->defaultAttsNames.parser)
|
||||
+ hashTableInit(&(ret->defaultAttsNames), getRootParserOf(parser, NULL));
|
||||
if (ret->name != name)
|
||||
poolDiscard(&dtd->pool);
|
||||
else {
|
||||
--
|
||||
2.52.0
|
||||
|
||||
|
||||
From 756dfc0850eb52005366da45859b1bb80a80466e Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Pipping <sebastian@pipping.org>
|
||||
Date: Sun, 8 Mar 2026 23:06:29 +0100
|
||||
Subject: [PATCH 6/6] lib: Leverage ELEMENT_TYPE.defaultAttsNames for attribute
|
||||
collision detection
|
||||
|
||||
.. to resolve quadratic runtime behavior
|
||||
---
|
||||
expat/lib/xmlparse.c | 14 ++++++++++----
|
||||
1 file changed, 10 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/expat/lib/xmlparse.c b/expat/lib/xmlparse.c
|
||||
index d8e7335d..d7d815e8 100644
|
||||
--- a/expat/lib/xmlparse.c
|
||||
+++ b/expat/lib/xmlparse.c
|
||||
@@ -7009,10 +7009,10 @@ defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
|
||||
if (value || isId) {
|
||||
/* The handling of default attributes gets messed up if we have
|
||||
a default which duplicates a non-default. */
|
||||
- int i;
|
||||
- for (i = 0; i < type->nDefaultAtts; i++)
|
||||
- if (attId == type->defaultAtts[i].id)
|
||||
- return 1;
|
||||
+ NAMED *const nameFound
|
||||
+ = (NAMED *)lookup(parser, &(type->defaultAttsNames), attId->name, 0);
|
||||
+ if (nameFound)
|
||||
+ return 1;
|
||||
if (isId && ! type->idAtt && ! attId->xmlns)
|
||||
type->idAtt = attId;
|
||||
}
|
||||
@@ -7059,6 +7059,12 @@ defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
|
||||
att->isCdata = isCdata;
|
||||
if (! isCdata)
|
||||
attId->maybeTokenized = XML_TRUE;
|
||||
+
|
||||
+ NAMED *const nameAddedOrFound = (NAMED *)lookup(
|
||||
+ parser, &(type->defaultAttsNames), attId->name, sizeof(NAMED));
|
||||
+ if (! nameAddedOrFound)
|
||||
+ return 0;
|
||||
+
|
||||
type->nDefaultAtts += 1;
|
||||
return 1;
|
||||
}
|
||||
--
|
||||
2.52.0
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,288 +0,0 @@
|
||||
From b5b73d23072fd277b3816b45c027238260467947 Mon Sep 17 00:00:00 2001
|
||||
From: Matthew Fernandez <matthew.fernandez@gmail.com>
|
||||
Date: Thu, 4 Jun 2026 17:01:02 -0700
|
||||
Subject: [PATCH 1/5] lib: Remove reuse of `m_groupSize` to count
|
||||
`m_scaffIndex` allocation
|
||||
|
||||
The sizes of the two arrays `m_groupConnector` and `scaffIndex` need to
|
||||
vary independently. This change is a step towards allowing this.
|
||||
|
||||
Anthropic: ANT-2026-00037
|
||||
Anthropic: ANT-2026-03621
|
||||
Anthropic: ANT-2026-03867
|
||||
Co-authored-by: Alessandro Gario <alessandro.gario@trailofbits.com>
|
||||
---
|
||||
expat/lib/xmlparse.c | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/expat/lib/xmlparse.c b/expat/lib/xmlparse.c
|
||||
index d7d815e8..3b5e90b1 100644
|
||||
--- a/expat/lib/xmlparse.c
|
||||
+++ b/expat/lib/xmlparse.c
|
||||
@@ -398,6 +398,7 @@ typedef struct {
|
||||
unsigned scaffCount;
|
||||
int scaffLevel;
|
||||
int *scaffIndex;
|
||||
+ size_t scaffIndexSize;
|
||||
} DTD;
|
||||
|
||||
enum EntityType {
|
||||
@@ -5812,6 +5813,7 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
|
||||
if (new_scaff_index == NULL)
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
dtd->scaffIndex = new_scaff_index;
|
||||
+ dtd->scaffIndexSize = parser->m_groupSize;
|
||||
}
|
||||
} else {
|
||||
parser->m_groupConnector
|
||||
@@ -7358,6 +7360,7 @@ dtdCreate(XML_Parser parser) {
|
||||
|
||||
p->in_eldecl = XML_FALSE;
|
||||
p->scaffIndex = NULL;
|
||||
+ p->scaffIndexSize = 0;
|
||||
p->scaffold = NULL;
|
||||
p->scaffLevel = 0;
|
||||
p->scaffSize = 0;
|
||||
@@ -7399,6 +7402,7 @@ dtdReset(DTD *p, XML_Parser parser) {
|
||||
|
||||
FREE(parser, p->scaffIndex);
|
||||
p->scaffIndex = NULL;
|
||||
+ p->scaffIndexSize = 0;
|
||||
FREE(parser, p->scaffold);
|
||||
p->scaffold = NULL;
|
||||
|
||||
@@ -7586,6 +7590,7 @@ dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd,
|
||||
newDtd->scaffSize = oldDtd->scaffSize;
|
||||
newDtd->scaffLevel = oldDtd->scaffLevel;
|
||||
newDtd->scaffIndex = oldDtd->scaffIndex;
|
||||
+ newDtd->scaffIndexSize = oldDtd->scaffIndexSize;
|
||||
|
||||
return 1;
|
||||
} /* End dtdCopy */
|
||||
@@ -8090,6 +8095,7 @@ nextScaffoldPart(XML_Parser parser) {
|
||||
dtd->scaffIndex = (int *)MALLOC(parser, parser->m_groupSize * sizeof(int));
|
||||
if (! dtd->scaffIndex)
|
||||
return -1;
|
||||
+ dtd->scaffIndexSize = parser->m_groupSize;
|
||||
dtd->scaffIndex[0] = 0;
|
||||
}
|
||||
|
||||
|
||||
From af2f86e32624be829ddc0ce7168d18f921bdef4e Mon Sep 17 00:00:00 2001
|
||||
From: Matthew Fernandez <matthew.fernandez@gmail.com>
|
||||
Date: Thu, 4 Jun 2026 17:01:02 -0700
|
||||
Subject: [PATCH 2/5] lib: doProlog: Fix out-of-bound scaffolding index store
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The scaffold backing array is reallocated using the caller parser’s
|
||||
per-parser `m_groupSize`, but the DTD struct (which carries
|
||||
`scaffIndex`) is shared between a parent parser and any external
|
||||
parameter-entity sub-parser created via
|
||||
`XML_ExternalEntityParserCreate(parent, NULL, …)`. A sub-parser whose
|
||||
group nesting is shallower than the parent’s can `REALLOC` the shared
|
||||
`scaffIndex` down to its own size; when the parent resumes and parses a
|
||||
deeper element content model, its bounds check passes (its private
|
||||
`m_groupSize` is still large enough), the doubling-grow path is skipped,
|
||||
and the next write lands past the shrunken buffer.
|
||||
|
||||
Anthropic: ANT-2026-00037
|
||||
Anthropic: ANT-2026-03621
|
||||
Anthropic: ANT-2026-03867
|
||||
Co-authored-by: Alessandro Gario <alessandro.gario@trailofbits.com>
|
||||
Reported-by: Trail of Bits, in collaboration with Anthropic
|
||||
---
|
||||
expat/lib/xmlparse.c | 15 +++++++++++++++
|
||||
1 file changed, 15 insertions(+)
|
||||
|
||||
diff --git a/expat/lib/xmlparse.c b/expat/lib/xmlparse.c
|
||||
index 3b5e90b1..317b08e0 100644
|
||||
--- a/expat/lib/xmlparse.c
|
||||
+++ b/expat/lib/xmlparse.c
|
||||
@@ -5830,6 +5830,21 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
|
||||
if (myindex < 0)
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
assert(dtd->scaffIndex != NULL);
|
||||
+ if ((size_t)dtd->scaffLevel >= dtd->scaffIndexSize) {
|
||||
+ /* Detect and prevent integer overflow */
|
||||
+ if (dtd->scaffIndexSize > SIZE_MAX / 2 / sizeof(int)) {
|
||||
+ return XML_ERROR_NO_MEMORY;
|
||||
+ }
|
||||
+ assert(dtd->scaffIndexSize > 0);
|
||||
+ const size_t new_size = dtd->scaffIndexSize * 2;
|
||||
+ int *const new_scaff_index
|
||||
+ = REALLOC(parser, dtd->scaffIndex, new_size * sizeof(int));
|
||||
+ if (new_scaff_index == NULL) {
|
||||
+ return XML_ERROR_NO_MEMORY;
|
||||
+ }
|
||||
+ dtd->scaffIndex = new_scaff_index;
|
||||
+ dtd->scaffIndexSize = new_size;
|
||||
+ }
|
||||
dtd->scaffIndex[dtd->scaffLevel] = myindex;
|
||||
dtd->scaffLevel++;
|
||||
dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
|
||||
|
||||
From 8b1debf703fadb5e11074f98f33a8bd10b561f3e Mon Sep 17 00:00:00 2001
|
||||
From: Matthew Fernandez <matthew.fernandez@gmail.com>
|
||||
Date: Thu, 4 Jun 2026 17:01:02 -0700
|
||||
Subject: [PATCH 3/5] tests: Add a test case for scaffolding array limits in
|
||||
shared DTDs
|
||||
|
||||
This test case provokes the bug fixed in the previous commit.
|
||||
|
||||
Anthropic: ANT-2026-00037
|
||||
Anthropic: ANT-2026-03621
|
||||
Anthropic: ANT-2026-03867
|
||||
Co-authored-by: Alessandro Gario <alessandro.gario@trailofbits.com>
|
||||
Reported-by: Trail of Bits, in collaboration with Anthropic
|
||||
---
|
||||
expat/tests/runtests.c | 30 ++++++++++++++++++++++++++++++
|
||||
1 file changed, 30 insertions(+)
|
||||
|
||||
diff --git a/expat/tests/runtests.c b/expat/tests/runtests.c
|
||||
index 659ed030..c760733d 100644
|
||||
--- a/expat/tests/runtests.c
|
||||
+++ b/expat/tests/runtests.c
|
||||
@@ -5681,6 +5681,34 @@ START_TEST(test_skipped_external_entity) {
|
||||
}
|
||||
END_TEST
|
||||
|
||||
+START_TEST(test_scaff_index_shared_across_external_entity_parser) {
|
||||
+ const char text[]
|
||||
+ = "<!DOCTYPE doc [\n"
|
||||
+ "<!ELEMENT a "
|
||||
+ "((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((b))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))>\n"
|
||||
+ "<!ENTITY % e SYSTEM 'ext'>\n"
|
||||
+ "%e;\n"
|
||||
+ "<!ELEMENT c "
|
||||
+ "(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((d)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))>\n"
|
||||
+ "]>\n"
|
||||
+ "<doc/>";
|
||||
+ ExtOption options[]
|
||||
+ = {{XCS("ext"),
|
||||
+ "<!ELEMENT x "
|
||||
+ "((((((((((((((((((((((((((((((((y))))))))))))))))))))))))))))))))>"},
|
||||
+ {NULL, NULL}};
|
||||
+
|
||||
+ XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
|
||||
+ XML_SetUserData(g_parser, options);
|
||||
+ XML_SetExternalEntityRefHandler(g_parser, external_entity_optioner);
|
||||
+ XML_SetElementDeclHandler(g_parser, dummy_element_decl_handler);
|
||||
+
|
||||
+ if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
|
||||
+ == XML_STATUS_ERROR)
|
||||
+ xml_failure(g_parser);
|
||||
+}
|
||||
+END_TEST
|
||||
+
|
||||
/* Test a different form of unknown external entity */
|
||||
typedef struct ext_hdlr_data {
|
||||
const char *parse_text;
|
||||
@@ -13988,6 +14016,8 @@ make_suite(void) {
|
||||
tcase_add_test(tc_basic, test_trailing_cr_in_att_value);
|
||||
tcase_add_test(tc_basic, test_standalone_internal_entity);
|
||||
tcase_add_test(tc_basic, test_skipped_external_entity);
|
||||
+ tcase_add_test__ifdef_xml_dtd(
|
||||
+ tc_basic, test_scaff_index_shared_across_external_entity_parser);
|
||||
tcase_add_test(tc_basic, test_skipped_null_loaded_ext_entity);
|
||||
tcase_add_test(tc_basic, test_skipped_unloaded_ext_entity);
|
||||
tcase_add_test__ifdef_xml_dtd(tc_basic, test_param_entity_with_trailing_cr);
|
||||
|
||||
From 4ab78126be566310e293adef807a9b919e90f8df Mon Sep 17 00:00:00 2001
|
||||
From: Matthew Fernandez <matthew.fernandez@gmail.com>
|
||||
Date: Thu, 4 Jun 2026 17:01:02 -0700
|
||||
Subject: [PATCH 4/5] lib: Remove unnecessary `scaffIndex` expansion
|
||||
|
||||
Following the previous changes, all locations that append entries to
|
||||
`scaffIndex` handle expanding the array if it is not already large
|
||||
enough. So this extra expansion code is no longer necessary. In some
|
||||
cases such as processing siblings with alternating scaffolding counts,
|
||||
this logic would actually _shrink_ the array only to then later
|
||||
re-expand it.
|
||||
|
||||
Anthropic: ANT-2026-00037
|
||||
Anthropic: ANT-2026-03621
|
||||
Anthropic: ANT-2026-03867
|
||||
Co-authored-by: Alessandro Gario <alessandro.gario@trailofbits.com>
|
||||
---
|
||||
expat/lib/xmlparse.c | 18 ------------------
|
||||
1 file changed, 18 deletions(-)
|
||||
|
||||
diff --git a/expat/lib/xmlparse.c b/expat/lib/xmlparse.c
|
||||
index 317b08e0..80fcb968 100644
|
||||
--- a/expat/lib/xmlparse.c
|
||||
+++ b/expat/lib/xmlparse.c
|
||||
@@ -5797,24 +5797,6 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
|
||||
parser->m_groupConnector = new_connector;
|
||||
}
|
||||
|
||||
- if (dtd->scaffIndex) {
|
||||
- /* Detect and prevent integer overflow.
|
||||
- * The preprocessor guard addresses the "always false" warning
|
||||
- * from -Wtype-limits on platforms where
|
||||
- * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
|
||||
-#if UINT_MAX >= SIZE_MAX
|
||||
- if (parser->m_groupSize > (size_t)(-1) / sizeof(int)) {
|
||||
- return XML_ERROR_NO_MEMORY;
|
||||
- }
|
||||
-#endif
|
||||
-
|
||||
- int *const new_scaff_index = (int *)REALLOC(
|
||||
- parser, dtd->scaffIndex, parser->m_groupSize * sizeof(int));
|
||||
- if (new_scaff_index == NULL)
|
||||
- return XML_ERROR_NO_MEMORY;
|
||||
- dtd->scaffIndex = new_scaff_index;
|
||||
- dtd->scaffIndexSize = parser->m_groupSize;
|
||||
- }
|
||||
} else {
|
||||
parser->m_groupConnector
|
||||
= (char *)MALLOC(parser, parser->m_groupSize = 32);
|
||||
|
||||
From 9a4202e63b9a89e2e1ec14996934ff98697c6721 Mon Sep 17 00:00:00 2001
|
||||
From: Matthew Fernandez <matthew.fernandez@gmail.com>
|
||||
Date: Thu, 4 Jun 2026 17:01:02 -0700
|
||||
Subject: [PATCH 5/5] lib: Remove indented scoping of `new_connector` local
|
||||
|
||||
Following the previous change, the lifetime of `new_connector` as
|
||||
constrained by this introduced scope was identical to the parent scope.
|
||||
---
|
||||
expat/lib/xmlparse.c | 23 ++++++++++-------------
|
||||
1 file changed, 10 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/expat/lib/xmlparse.c b/expat/lib/xmlparse.c
|
||||
index 80fcb968..5c255c00 100644
|
||||
--- a/expat/lib/xmlparse.c
|
||||
+++ b/expat/lib/xmlparse.c
|
||||
@@ -5782,21 +5782,18 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
|
||||
case XML_ROLE_GROUP_OPEN:
|
||||
if (parser->m_prologState.level >= parser->m_groupSize) {
|
||||
if (parser->m_groupSize) {
|
||||
- {
|
||||
- /* Detect and prevent integer overflow */
|
||||
- if (parser->m_groupSize > (unsigned int)(-1) / 2u) {
|
||||
- return XML_ERROR_NO_MEMORY;
|
||||
- }
|
||||
-
|
||||
- char *const new_connector = (char *)REALLOC(
|
||||
- parser, parser->m_groupConnector, parser->m_groupSize *= 2);
|
||||
- if (new_connector == NULL) {
|
||||
- parser->m_groupSize /= 2;
|
||||
- return XML_ERROR_NO_MEMORY;
|
||||
- }
|
||||
- parser->m_groupConnector = new_connector;
|
||||
+ /* Detect and prevent integer overflow */
|
||||
+ if (parser->m_groupSize > (unsigned int)(-1) / 2u) {
|
||||
+ return XML_ERROR_NO_MEMORY;
|
||||
}
|
||||
|
||||
+ char *const new_connector = (char *)REALLOC(
|
||||
+ parser, parser->m_groupConnector, parser->m_groupSize *= 2);
|
||||
+ if (new_connector == NULL) {
|
||||
+ parser->m_groupSize /= 2;
|
||||
+ return XML_ERROR_NO_MEMORY;
|
||||
+ }
|
||||
+ parser->m_groupConnector = new_connector;
|
||||
} else {
|
||||
parser->m_groupConnector
|
||||
= (char *)MALLOC(parser, parser->m_groupSize = 32);
|
||||
@ -3,7 +3,7 @@
|
||||
Summary: An XML parser library
|
||||
Name: expat
|
||||
Version: %(echo %{unversion} | sed 's/_/./g')
|
||||
Release: 2%{?dist}.2
|
||||
Release: 2%{?dist}
|
||||
Source: https://github.com/libexpat/libexpat/archive/R_%{unversion}.tar.gz#/expat-%{version}.tar.gz
|
||||
URL: https://libexpat.github.io/
|
||||
License: MIT
|
||||
@ -13,27 +13,6 @@ BuildRequires: make
|
||||
Patch0: expat-2.5.0-CVE-2023-52425.patch
|
||||
# https://issues.redhat.com/browse/RHEL-28700
|
||||
Patch1: expat-2.5.0-CVE-2024-28757.patch
|
||||
# https://issues.redhat.com/browse/RHEL-56761
|
||||
Patch2: expat-2.5.0-CVE-2024-45490.patch
|
||||
# https://issues.redhat.com/browse/RHEL-57520
|
||||
Patch3: expat-2.5.0-CVE-2024-45491.patch
|
||||
# https://issues.redhat.com/browse/RHEL-57511
|
||||
Patch4: expat-2.5.0-CVE-2024-45492.patch
|
||||
# https://issues.redhat.com/browse/RHEL-65066
|
||||
Patch5: expat-2.5.0-CVE-2024-50602.patch
|
||||
# https://issues.redhat.com/browse/RHEL-57489
|
||||
Patch6: expat-2.5.0-CVE-2024-8176.patch
|
||||
# https://issues.redhat.com/browse/RHEL-114618
|
||||
Patch7: expat-2.5.0-CVE-2025-59375.patch
|
||||
# https://issues.redhat.com/browse/RHEL-177979
|
||||
# https://github.com/libexpat/libexpat/pull/1216
|
||||
Patch8: expat-2.5.0-CVE-2026-45186.patch
|
||||
# https://issues.redhat.com/browse/RHEL-220979
|
||||
# https://github.com/libexpat/libexpat/pull/1246
|
||||
Patch9: expat-2.5.0-CVE-2026-50219.patch
|
||||
# https://issues.redhat.com/browse/RHEL-221012
|
||||
# https://github.com/libexpat/libexpat/pull/1272
|
||||
Patch10: expat-2.5.0-CVE-2026-56132.patch
|
||||
|
||||
%description
|
||||
This is expat, the C library for parsing XML, written by James Clark. Expat
|
||||
@ -64,15 +43,6 @@ Install it if you need to link statically with expat.
|
||||
pushd ..
|
||||
%patch0 -p1 -b .CVE-2023-52425
|
||||
%patch1 -p1 -b .CVE-2024-28757
|
||||
%patch2 -p1 -b .CVE-2024-45490
|
||||
%patch3 -p1 -b .CVE-2024-45491
|
||||
%patch4 -p1 -b .CVE-2024-45492
|
||||
%patch5 -p1 -b .CVE-2024-50602
|
||||
%patch6 -p1 -b .CVE-2024-8176
|
||||
%patch7 -p1 -b .CVE-2025-59375
|
||||
%patch8 -p1 -b .CVE-2026-45186
|
||||
%patch9 -p1 -b .CVE-2026-50219
|
||||
%patch10 -p1 -b .CVE-2026-56132
|
||||
popd
|
||||
|
||||
sed -i 's/install-data-hook/do-nothing-please/' lib/Makefile.am
|
||||
@ -82,21 +52,21 @@ sed -i 's/install-data-hook/do-nothing-please/' lib/Makefile.am
|
||||
export CFLAGS="$RPM_OPT_FLAGS -fPIC"
|
||||
export DOCBOOK_TO_MAN="xmlto man --skip-validation"
|
||||
%configure
|
||||
make %{?_smp_mflags}
|
||||
%make_build
|
||||
|
||||
%install
|
||||
make install DESTDIR=$RPM_BUILD_ROOT
|
||||
%make_install
|
||||
|
||||
rm -f $RPM_BUILD_ROOT%{_libdir}/*.la
|
||||
|
||||
%check
|
||||
bash -c "for i in {1..500000}; do printf AAAAAAAAAAAAAAAAAAAA >> achars.txt; done"
|
||||
for testfile in ../testdata/largefiles/aaaaaa_*; do
|
||||
first_part="$(sed 's/\(.*\)ACHARS.*/\1/g' $testfile)"
|
||||
second_part="$(sed 's/.*ACHARS\(.*\)/\1/g' $testfile)"
|
||||
printf "$first_part" > "$testfile"
|
||||
cat achars.txt >> "$testfile"
|
||||
printf "$second_part" >> "$testfile"
|
||||
first_part="$(sed 's/\(.*\)ACHARS.*/\1/g' $testfile)"
|
||||
second_part="$(sed 's/.*ACHARS\(.*\)/\1/g' $testfile)"
|
||||
printf "$first_part" > "$testfile"
|
||||
cat achars.txt >> "$testfile"
|
||||
printf "$second_part" >> "$testfile"
|
||||
done
|
||||
|
||||
make check
|
||||
@ -104,7 +74,6 @@ make check
|
||||
%ldconfig_scriptlets
|
||||
|
||||
%files
|
||||
%{!?_licensedir:%global license %%doc}
|
||||
%doc AUTHORS Changes
|
||||
%license COPYING
|
||||
%{_bindir}/*
|
||||
@ -122,73 +91,32 @@ make check
|
||||
%{_libdir}/lib*.a
|
||||
|
||||
%changelog
|
||||
* Fri Jul 31 2026 RHEL Packaging Agent <redhat-ymir-agent@redhat.com> - 2.5.0-2.2
|
||||
- Fix CVE-2026-56132: out-of-bound scaffolding index store in doProlog
|
||||
- Resolves: RHEL-221012
|
||||
* Tue Feb 13 2024 Tomas Korbar <tkorbar@redhat.com> - 2.5.0-2
|
||||
- Fix parsing of large tokens
|
||||
- Reject direct parameter entity recursion
|
||||
- Resolves: RHEL-29699
|
||||
- Resolves: RHEL-29696
|
||||
|
||||
* Fri Jul 31 2026 RHEL Packaging Agent <redhat-ymir-agent@redhat.com> - 2.5.0-2.1
|
||||
- Fix CVE-2026-50219
|
||||
- Resolves: RHEL-220979
|
||||
|
||||
* Thu May 28 2026 RHEL Packaging Agent <redhat-ymir-agent@redhat.com> - 2.5.0-2
|
||||
- Fix CVE-2026-45186
|
||||
- Resolves: RHEL-177979
|
||||
|
||||
* Wed Nov 19 2025 Tomas Korbar <tkorbar@redhat.com> - 2.5.0-1
|
||||
* Thu Nov 10 2022 Tomas Korbar <tkorbar@redhat.com> - 2.5.0-1
|
||||
- Rebase to version 2.5.0
|
||||
- Fix CVE-2025-59375
|
||||
- Resolves: RHEL-114618
|
||||
|
||||
* Mon Apr 07 2025 Tomas Korbar <tkorbar@redhat.com> - 2.2.5-17
|
||||
- Fix CVE-2024-8176
|
||||
- Resolves: RHEL-57477
|
||||
|
||||
* Fri Nov 08 2024 Tomas Korbar <tkorbar@redhat.com> - 2.2.5-16
|
||||
- Fix CVE-2024-50602
|
||||
- Resolves: RHEL-65062
|
||||
|
||||
* Wed Sep 11 2024 Tomas Korbar <tkorbar@redhat.com> - 2.2.5-15
|
||||
- Rebuild for test reconfiguration
|
||||
|
||||
* Wed Sep 11 2024 Tomas Korbar <tkorbar@redhat.com> - 2.2.5-14
|
||||
- Fix multiple CVEs
|
||||
- Fix CVE-2024-45492 integer overflow
|
||||
- Fix CVE-2024-45491 Integer Overflow or Wraparound
|
||||
- Fix CVE-2024-45490 Negative Length Parsing Vulnerability
|
||||
- Resolves: RHEL-57505
|
||||
- Resolves: RHEL-57493
|
||||
- Resolves: RHEL-56751
|
||||
|
||||
* Tue Mar 26 2024 Tomas Korbar <tkorbar@redhat.com> - 2.2.5-13
|
||||
- Fix wrongly exposed variables
|
||||
- Resolves: RHEL-29321
|
||||
|
||||
* Thu Mar 21 2024 Tomas Korbar <tkorbar@redhat.com> - 2.2.5-12
|
||||
- CVE-2023-52425 expat: parsing large tokens can trigger a denial of service
|
||||
- Resolves: RHEL-29321
|
||||
|
||||
* Mon Nov 14 2022 Tomas Korbar <tkorbar@redhat.com> - 2.2.5-11
|
||||
- CVE-2022-43680 expat: use-after free caused by overeager destruction of a shared DTD in XML_ExternalEntityParserCreate
|
||||
- Resolves: CVE-2022-43680
|
||||
|
||||
* Fri Sep 30 2022 Tomas Korbar <tkorbar@redhat.com> - 2.2.5-10
|
||||
- Ensure raw tagnames are safe exiting internalEntityParser
|
||||
* Thu Sep 29 2022 Tomas Korbar <tkorbar@redhat.com> - 2.4.9-1
|
||||
- Rebase to version 2.4.9
|
||||
- Resolves: CVE-2022-40674
|
||||
|
||||
* Fri May 06 2022 Tomas Korbar <tkorbar@redhat.com> - 2.2.5-9
|
||||
- Fix multiple CVEs
|
||||
- Resolves: CVE-2022-25314
|
||||
* Tue Apr 26 2022 Tomas Korbar <tkorbar@redhat.com> - 2.4.7-1
|
||||
- Rebase to version 2.4.7
|
||||
- Resolves: rhbz#2067201
|
||||
- Resolves: CVE-2022-25313
|
||||
- Resolves: CVE-2022-25314
|
||||
- Resolves: CVE-2022-25236
|
||||
|
||||
* Mon Mar 14 2022 Tomas Korbar <tkorbar@redhat.com> - 2.2.5-8
|
||||
- Improve patch for CVE-2022-25236
|
||||
* Mon Mar 14 2022 Tomas Korbar <tkorbar@redhat.com> - 2.2.10-11
|
||||
- Improve fix for CVE-2022-25236
|
||||
- Related: CVE-2022-25236
|
||||
|
||||
* Fri Mar 04 2022 Tomas Korbar <tkorbar@redhat.com> - 2.2.5-7
|
||||
- Fix patch for CVE-2022-25235
|
||||
- Resolves: CVE-2022-25235
|
||||
|
||||
* Thu Mar 03 2022 Tomas Korbar <tkorbar@redhat.com> - 2.2.5-6
|
||||
* Mon Feb 28 2022 Tomas Korbar <tkorbar@redhat.com> - 2.2.10-10
|
||||
- Fix multiple CVEs
|
||||
- CVE-2022-25236 expat: namespace-separator characters in "xmlns[:prefix]" attribute values can lead to arbitrary code execution
|
||||
- CVE-2022-25235 expat: malformed 2- and 3-byte UTF-8 sequences can lead to arbitrary code execution
|
||||
@ -197,20 +125,25 @@ make check
|
||||
- Resolves: CVE-2022-25235
|
||||
- Resolves: CVE-2022-25315
|
||||
|
||||
* Fri Feb 14 2022 Tomas Korbar <tkorbar@redhat.com> - 2.2.5-5
|
||||
- Fix multiple CVEs
|
||||
* Thu Feb 10 2022 Tomas Korbar <tkorbar@redhat.com> - 2.2.10-9
|
||||
- CVE-2022-23852 expat: integer overflow in function XML_GetBuffer
|
||||
- Resolves: CVE-2022-23852
|
||||
|
||||
* Thu Feb 10 2022 Tomas Korbar <tkorbar@redhat.com> - 2.2.10-8
|
||||
- CVE-2021-45960 expat: Large number of prefixed XML attributes on a single tag can crash libexpat
|
||||
- Resolves: CVE-2021-45960
|
||||
|
||||
* Wed Feb 09 2022 Tomas Korbar <tkorbar@redhat.com> - 2.2.10-7
|
||||
- CVE-2021-46143 expat: Integer overflow in doProlog in xmlparse.c
|
||||
- Resolves: CVE-2021-46143
|
||||
|
||||
* Wed Feb 09 2022 Tomas Korbar <tkorbar@redhat.com> - 2.2.10-6
|
||||
- CVE-2022-22827 Integer overflow in storeAtts in xmlparse.c
|
||||
- CVE-2022-22826 Integer overflow in nextScaffoldPart in xmlparse.c
|
||||
- CVE-2022-22825 Integer overflow in lookup in xmlparse.c
|
||||
- CVE-2022-22824 Integer overflow in defineAttribute in xmlparse.c
|
||||
- CVE-2022-22823 Integer overflow in build_model in xmlparse.c
|
||||
- CVE-2022-22822 Integer overflow in addBinding in xmlparse.c
|
||||
- Resolves: CVE-2022-23852
|
||||
- Resolves: CVE-2021-45960
|
||||
- Resolves: CVE-2021-46143
|
||||
- Resolves: CVE-2022-22827
|
||||
- Resolves: CVE-2022-22826
|
||||
- Resolves: CVE-2022-22825
|
||||
@ -218,8 +151,46 @@ make check
|
||||
- Resolves: CVE-2022-22823
|
||||
- Resolves: CVE-2022-22822
|
||||
|
||||
* Fri Apr 24 2020 Joe Orton <jorton@redhat.com> - 2.2.5-4
|
||||
- add security fixes for CVE-2018-20843, CVE-2019-15903
|
||||
* Mon Feb 07 2022 Tomas Korbar <tkorbar@redhat.com> - 2.2.10-5
|
||||
- CVE-2022-23990 expat: integer overflow in the doProlog function
|
||||
- Resolve: rhbz#2050503
|
||||
|
||||
* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 2.2.10-4
|
||||
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
|
||||
Related: rhbz#1991688
|
||||
|
||||
* Thu Apr 15 2021 Mohan Boddu <mboddu@redhat.com> - 2.2.10-3
|
||||
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
|
||||
|
||||
* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 2.2.10-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
|
||||
|
||||
* Fri Nov 13 2020 Joe Orton <jorton@redhat.com> - 2.2.10-1
|
||||
- update to 2.2.10 (#1884940)
|
||||
|
||||
* Mon Jul 27 2020 Fedora Release Engineering <releng@fedoraproject.org> - 2.2.8-3
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
|
||||
|
||||
* Tue Jan 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 2.2.8-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
|
||||
|
||||
* Mon Sep 16 2019 Joe Orton <jorton@redhat.com> - 2.2.8-1
|
||||
- update to 2.2.8 (#1752167)
|
||||
|
||||
* Thu Jul 25 2019 Fedora Release Engineering <releng@fedoraproject.org> - 2.2.7-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
|
||||
|
||||
* Thu Jun 27 2019 Joe Orton <jorton@redhat.com> - 2.2.7-1
|
||||
- update to 2.2.7 (#1723724, #1722224)
|
||||
|
||||
* Thu Jan 31 2019 Fedora Release Engineering <releng@fedoraproject.org> - 2.2.6-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
|
||||
|
||||
* Wed Aug 15 2018 Joe Orton <jorton@redhat.com> - 2.2.6-1
|
||||
- update to 2.2.6
|
||||
|
||||
* Fri Jul 13 2018 Fedora Release Engineering <releng@fedoraproject.org> - 2.2.5-4
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
|
||||
|
||||
* Wed Feb 07 2018 Fedora Release Engineering <releng@fedoraproject.org> - 2.2.5-3
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
|
||||
25
gating.yaml
Normal file
25
gating.yaml
Normal file
@ -0,0 +1,25 @@
|
||||
--- !Policy
|
||||
product_versions:
|
||||
- fedora-*
|
||||
decision_context: bodhi_update_push_testing
|
||||
subject_type: koji_build
|
||||
rules:
|
||||
- !PassingTestCaseRule {test_case_name: fedora-ci.koji-build./plans/tier1-public.functional}
|
||||
|
||||
#Rawhide
|
||||
--- !Policy
|
||||
product_versions:
|
||||
- fedora-*
|
||||
decision_context: bodhi_update_push_stable
|
||||
subject_type: koji_build
|
||||
rules:
|
||||
- !PassingTestCaseRule {test_case_name: fedora-ci.koji-build./plans/tier1-public.functional}
|
||||
|
||||
#gating rhel
|
||||
--- !Policy
|
||||
product_versions:
|
||||
- rhel-*
|
||||
decision_context: osci_compose_gate
|
||||
rules:
|
||||
- !PassingTestCaseRule {test_case_name: osci.brew-build./plans/tier1-public.functional}
|
||||
- !PassingTestCaseRule {test_case_name: osci.brew-build./plans/tier1-internal.functional}
|
||||
36
plans.fmf
Normal file
36
plans.fmf
Normal file
@ -0,0 +1,36 @@
|
||||
/tier1-internal:
|
||||
plan:
|
||||
import:
|
||||
url: https://src.fedoraproject.org/tests/expat.git
|
||||
name: /plans/tier1/internal
|
||||
|
||||
/tier1-public:
|
||||
plan:
|
||||
import:
|
||||
url: https://src.fedoraproject.org/tests/expat.git
|
||||
name: /plans/tier1/public
|
||||
|
||||
/tier2-tier3-internal:
|
||||
plan:
|
||||
import:
|
||||
url: https://src.fedoraproject.org/tests/expat.git
|
||||
name: /plans/tier2-tier3/internal
|
||||
|
||||
/tier2-tier3-public:
|
||||
plan:
|
||||
import:
|
||||
url: https://src.fedoraproject.org/tests/expat.git
|
||||
name: /plans/tier2-tier3/public
|
||||
|
||||
/others-internal:
|
||||
plan:
|
||||
import:
|
||||
url: https://src.fedoraproject.org/tests/expat.git
|
||||
name: /plans/others/internal
|
||||
|
||||
/others-public:
|
||||
plan:
|
||||
import:
|
||||
url: https://src.fedoraproject.org/tests/expat.git
|
||||
name: /plans/others/public
|
||||
|
||||
Loading…
Reference in New Issue
Block a user