Compare commits

...

No commits in common. "c8" and "c8-beta" have entirely different histories.
c8 ... c8-beta

15 changed files with 1 additions and 1647 deletions

View File

@ -1,32 +0,0 @@
From d0c3f01e110d54415611c5fa0040cdf4a56053f9 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Sat, 6 May 2023 17:47:37 +0200
Subject: [PATCH] parser: Fix old SAX1 parser with custom callbacks
For some reason, xmlCtxtUseOptionsInternal set the start and end element
SAX handlers to the internal DOM builder functions when XML_PARSE_SAX1
was specified. This means that custom SAX handlers could never work with
that flag because these functions would receive the wrong user data
argument and crash immediately.
Fixes #535.
---
parser.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/parser.c b/parser.c
index bb05791d3..0c8bed129 100644
--- a/parser.c
+++ b/parser.c
@@ -14479,8 +14479,6 @@ xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options, const char *encodi
}
#ifdef LIBXML_SAX1_ENABLED
if (options & XML_PARSE_SAX1) {
- ctxt->sax->startElement = xmlSAX2StartElement;
- ctxt->sax->endElement = xmlSAX2EndElement;
ctxt->sax->startElementNs = NULL;
ctxt->sax->endElementNs = NULL;
ctxt->sax->initialized = 1;
--
GitLab

View File

@ -1,38 +0,0 @@
From 384cc7c182fc00c6d5e2ab4b5e3671b2e3f93c84 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Sun, 6 Apr 2025 12:41:11 +0200
Subject: [PATCH] [CVE-2025-32415] schemas: Fix heap buffer overflow in
xmlSchemaIDCFillNodeTables
Don't use local variable which could contain a stale value.
Fixes #890.
---
xmlschemas.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/xmlschemas.c b/xmlschemas.c
index e35c117ef..4bdabd129 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -23324,7 +23324,7 @@ xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt,
j++;
} while (j < nbDupls);
}
- if (nbNodeTable) {
+ if (bind->nbNodes) {
j = 0;
do {
if (nbFields == 1) {
@@ -23375,7 +23375,7 @@ xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt,
next_node_table_entry:
j++;
- } while (j < nbNodeTable);
+ } while (j < bind->nbNodes);
}
/*
* If everything is fine, then add the IDC target-node to
--
GitLab

View File

@ -1,34 +0,0 @@
From 6bb146a3ea24a9bacfad6fe67268f0404af37d9c Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Wed, 2 Nov 2022 16:13:27 +0100
Subject: [PATCH] malloc-fail: Fix use-after-free in xmlXIncludeAddNode
Found with libFuzzer, see #344.
---
xinclude.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/xinclude.c b/xinclude.c
index 2a0614d7..e32b3419 100644
--- a/xinclude.c
+++ b/xinclude.c
@@ -614,14 +614,15 @@ xmlXIncludeAddNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr cur) {
}
URL = xmlSaveUri(uri);
xmlFreeURI(uri);
- xmlFree(URI);
if (URL == NULL) {
xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_HREF_URI,
"invalid value URI %s\n", URI);
if (fragment != NULL)
xmlFree(fragment);
+ xmlFree(URI);
return(-1);
}
+ xmlFree(URI);
/*
* If local and xml then we need a fragment
--
2.48.1

View File

@ -1,71 +0,0 @@
From 4c6922f763ad958c48ff66f82823ae21f2e92ee6 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Tue, 13 Sep 2022 16:40:31 +0200
Subject: [PATCH] schemas: Fix null-pointer-deref in
xmlSchemaCheckCOSSTDerivedOK
Found by OSS-Fuzz.
---
result/schemas/oss-fuzz-51295_0_0.err | 2 ++
test/schemas/oss-fuzz-51295_0.xml | 1 +
test/schemas/oss-fuzz-51295_0.xsd | 4 ++++
xmlschemas.c | 15 +++++++++++++--
4 files changed, 20 insertions(+), 2 deletions(-)
create mode 100644 result/schemas/oss-fuzz-51295_0_0.err
create mode 100644 test/schemas/oss-fuzz-51295_0.xml
create mode 100644 test/schemas/oss-fuzz-51295_0.xsd
diff --git a/result/schemas/oss-fuzz-51295_0_0.err b/result/schemas/oss-fuzz-51295_0_0.err
new file mode 100644
index 00000000..1e89524f
--- /dev/null
+++ b/result/schemas/oss-fuzz-51295_0_0.err
@@ -0,0 +1,2 @@
+./test/schemas/oss-fuzz-51295_0.xsd:2: element element: Schemas parser error : element decl. 'e': The element declaration 'e' defines a circular substitution group to element declaration 'e'.
+./test/schemas/oss-fuzz-51295_0.xsd:2: element element: Schemas parser error : element decl. 'e': The element declaration 'e' defines a circular substitution group to element declaration 'e'.
diff --git a/test/schemas/oss-fuzz-51295_0.xml b/test/schemas/oss-fuzz-51295_0.xml
new file mode 100644
index 00000000..10a7e703
--- /dev/null
+++ b/test/schemas/oss-fuzz-51295_0.xml
@@ -0,0 +1 @@
+<e/>
diff --git a/test/schemas/oss-fuzz-51295_0.xsd b/test/schemas/oss-fuzz-51295_0.xsd
new file mode 100644
index 00000000..fde96af5
--- /dev/null
+++ b/test/schemas/oss-fuzz-51295_0.xsd
@@ -0,0 +1,4 @@
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:element name="e" substitutionGroup="e"/>
+ <xs:element name="t" substitutionGroup="e" type='xs:decimal'/>
+</xs:schema>
diff --git a/xmlschemas.c b/xmlschemas.c
index f31d3d1f..152b7c3f 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -13345,8 +13345,19 @@ xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl,
* declaration `resolved` to by the `actual value`
* of the substitutionGroup [attribute], if present"
*/
- if (elemDecl->subtypes == NULL)
- elemDecl->subtypes = substHead->subtypes;
+ if (elemDecl->subtypes == NULL) {
+ if (substHead->subtypes == NULL) {
+ /*
+ * This can happen with self-referencing substitution
+ * groups. The cycle will be detected later, but we have
+ * to set subtypes to avoid null-pointer dereferences.
+ */
+ elemDecl->subtypes = xmlSchemaGetBuiltInType(
+ XML_SCHEMAS_ANYTYPE);
+ } else {
+ elemDecl->subtypes = substHead->subtypes;
+ }
+ }
}
}
/*
--
GitLab

View File

@ -1,74 +0,0 @@
From 647e072ea0a2f12687fa05c172f4c4713fdb0c4f Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Fri, 7 Apr 2023 11:46:35 +0200
Subject: [PATCH] [CVE-2023-28484] Fix null deref in xmlSchemaFixupComplexType
Fix a null pointer dereference when parsing (invalid) XML schemas.
Thanks to Robby Simpson for the report!
Fixes #491.
---
result/schemas/issue491_0_0.err | 1 +
test/schemas/issue491_0.xml | 1 +
test/schemas/issue491_0.xsd | 18 ++++++++++++++++++
xmlschemas.c | 2 +-
4 files changed, 21 insertions(+), 1 deletion(-)
create mode 100644 result/schemas/issue491_0_0.err
create mode 100644 test/schemas/issue491_0.xml
create mode 100644 test/schemas/issue491_0.xsd
diff --git a/result/schemas/issue491_0_0.err b/result/schemas/issue491_0_0.err
new file mode 100644
index 00000000..9b2bb969
--- /dev/null
+++ b/result/schemas/issue491_0_0.err
@@ -0,0 +1 @@
+./test/schemas/issue491_0.xsd:8: element complexType: Schemas parser error : complex type 'ChildType': The content type of both, the type and its base type, must either 'mixed' or 'element-only'.
diff --git a/test/schemas/issue491_0.xml b/test/schemas/issue491_0.xml
new file mode 100644
index 00000000..e2b2fc2e
--- /dev/null
+++ b/test/schemas/issue491_0.xml
@@ -0,0 +1 @@
+<Child xmlns="http://www.test.com">5</Child>
diff --git a/test/schemas/issue491_0.xsd b/test/schemas/issue491_0.xsd
new file mode 100644
index 00000000..81702649
--- /dev/null
+++ b/test/schemas/issue491_0.xsd
@@ -0,0 +1,18 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.test.com" targetNamespace="http://www.test.com" elementFormDefault="qualified" attributeFormDefault="unqualified">
+ <xs:complexType name="BaseType">
+ <xs:simpleContent>
+ <xs:extension base="xs:int" />
+ </xs:simpleContent>
+ </xs:complexType>
+ <xs:complexType name="ChildType">
+ <xs:complexContent>
+ <xs:extension base="BaseType">
+ <xs:sequence>
+ <xs:element name="bad" type="xs:int" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="Child" type="ChildType" />
+</xs:schema>
diff --git a/xmlschemas.c b/xmlschemas.c
index 152b7c3f..eec24a95 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -18619,7 +18619,7 @@ xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt,
"allowed to appear inside other model groups",
NULL, NULL);
- } else if (! dummySequence) {
+ } else if ((!dummySequence) && (baseType->subtypes != NULL)) {
xmlSchemaTreeItemPtr effectiveContent =
(xmlSchemaTreeItemPtr) type->subtypes;
/*
--
GitLab

View File

@ -1,41 +0,0 @@
From 245b70d7d2768572ae1b05b3668ca858b9ec4ed4 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Tue, 10 Dec 2024 16:52:05 +0100
Subject: [PATCH] [CVE-2024-56171] Fix use-after-free after
xmlSchemaItemListAdd
xmlSchemaItemListAdd can reallocate the items array. Update local
variables after adding item in
- xmlSchemaIDCFillNodeTables
- xmlSchemaBubbleIDCNodeTables
Fixes #828.
---
xmlschemas.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/xmlschemas.c b/xmlschemas.c
index d276faf10..28b14bd44 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -23388,6 +23388,7 @@ xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt,
}
if (xmlSchemaItemListAdd(bind->dupls, bind->nodeTable[j]) == -1)
goto internal_error;
+ dupls = (xmlSchemaPSVIIDCNodePtr *) bind->dupls->items;
/*
* Remove the duplicate entry from the IDC node-table.
*/
@@ -23604,6 +23605,8 @@ xmlSchemaBubbleIDCNodeTables(xmlSchemaValidCtxtPtr vctxt)
goto internal_error;
}
xmlSchemaItemListAdd(parBind->dupls, parNode);
+ dupls = (xmlSchemaPSVIIDCNodePtr *)
+ parBind->dupls->items;
} else {
/*
* Add the node-table entry (node and key-sequence) of
--
GitLab

View File

@ -1,57 +0,0 @@
From 858ca26c0689161a6b903a6682cc8a1cc10a0ea8 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Tue, 11 Feb 2025 17:30:40 +0100
Subject: [PATCH] [CVE-2025-24928] Fix stack-buffer-overflow in
xmlSnprintfElements
Fixes #847.
---
valid.c | 25 +++++++++++++------------
1 file changed, 13 insertions(+), 12 deletions(-)
diff --git a/valid.c b/valid.c
index 76d657d62..abefdc50a 100644
--- a/valid.c
+++ b/valid.c
@@ -5057,25 +5057,26 @@ xmlSnprintfElements(char *buf, int size, xmlNodePtr node, int glob) {
return;
}
switch (cur->type) {
- case XML_ELEMENT_NODE:
+ case XML_ELEMENT_NODE: {
+ int qnameLen = xmlStrlen(cur->name);
+
+ if ((cur->ns != NULL) && (cur->ns->prefix != NULL))
+ qnameLen += xmlStrlen(cur->ns->prefix) + 1;
+ if (size - len < qnameLen + 10) {
+ if ((size - len > 4) && (buf[len - 1] != '.'))
+ strcat(buf, " ...");
+ return;
+ }
if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
- if (size - len < xmlStrlen(cur->ns->prefix) + 10) {
- if ((size - len > 4) && (buf[len - 1] != '.'))
- strcat(buf, " ...");
- return;
- }
strcat(buf, (char *) cur->ns->prefix);
strcat(buf, ":");
}
- if (size - len < xmlStrlen(cur->name) + 10) {
- if ((size - len > 4) && (buf[len - 1] != '.'))
- strcat(buf, " ...");
- return;
- }
- strcat(buf, (char *) cur->name);
+ if (cur->name != NULL)
+ strcat(buf, (char *) cur->name);
if (cur->next != NULL)
strcat(buf, " ");
break;
+ }
case XML_TEXT_NODE:
if (xmlIsBlankNode(cur))
break;
--
GitLab

View File

@ -1,73 +0,0 @@
From c0fa8ea4b9a3fc0043e95622dcc4bf0a96199d57 Mon Sep 17 00:00:00 2001
From: Maks Verver <maks@verver.ch>
Date: Mon, 9 Jun 2025 20:09:17 +0100
Subject: [PATCH] [CVE-2025-32414] python: Read at most len/4 characters.
Fixes #889 by reserving space in the buffer for UTF-8 encoding of text.
---
python/libxml.c | 28 ++++++++++++++++++----------
1 file changed, 18 insertions(+), 10 deletions(-)
diff --git a/python/libxml.c b/python/libxml.c
index ef630254..f31e080f 100644
--- a/python/libxml.c
+++ b/python/libxml.c
@@ -287,7 +287,9 @@ xmlPythonFileReadRaw (void * context, char * buffer, int len) {
#endif
file = (PyObject *) context;
if (file == NULL) return(-1);
- ret = PyEval_CallMethod(file, (char *) "read", (char *) "(i)", len);
+ /* When read() returns a string, the length is in characters not bytes, so
+ request at most len / 4 characters to leave space for UTF-8 encoding. */
+ ret = PyEval_CallMethod(file, (char *) "read", (char *) "(i)", len / 4);
if (ret == NULL) {
printf("xmlPythonFileReadRaw: result is NULL\n");
return(-1);
@@ -322,10 +324,12 @@ xmlPythonFileReadRaw (void * context, char * buffer, int len) {
Py_DECREF(ret);
return(-1);
}
- if (lenread > len)
- memcpy(buffer, data, len);
- else
- memcpy(buffer, data, lenread);
+ if (lenread < 0 || lenread > len) {
+ printf("xmlPythonFileReadRaw: invalid lenread\n");
+ Py_DECREF(ret);
+ return(-1);
+ }
+ memcpy(buffer, data, lenread);
Py_DECREF(ret);
return(lenread);
}
@@ -352,7 +356,9 @@ xmlPythonFileRead (void * context, char * buffer, int len) {
#endif
file = (PyObject *) context;
if (file == NULL) return(-1);
- ret = PyEval_CallMethod(file, (char *) "io_read", (char *) "(i)", len);
+ /* When read() returns a string, the length is in characters not bytes, so
+ request at most len / 4 characters to leave space for UTF-8 encoding. */
+ ret = PyEval_CallMethod(file, (char *) "io_read", (char *) "(i)", len / 4);
if (ret == NULL) {
printf("xmlPythonFileRead: result is NULL\n");
return(-1);
@@ -387,10 +393,12 @@ xmlPythonFileRead (void * context, char * buffer, int len) {
Py_DECREF(ret);
return(-1);
}
- if (lenread > len)
- memcpy(buffer, data, len);
- else
- memcpy(buffer, data, lenread);
+ if (lenread < 0 || lenread > len) {
+ printf("xmlPythonFileRead: invalid lenread\n");
+ Py_DECREF(ret);
+ return(-1);
+ }
+ memcpy(buffer, data, lenread);
Py_DECREF(ret);
return(lenread);
}
--
2.49.0

View File

@ -1,194 +0,0 @@
From b2a28a861e9d43a23b877c3994daa28f8af69618 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Fri, 4 Jul 2025 14:28:26 +0200
Subject: [PATCH] schematron: Fix memory safety issues in
xmlSchematronReportOutput
Fix use-after-free (CVE-2025-49794) and type confusion (CVE-2025-49796)
in xmlSchematronReportOutput.
Fixes #931.
Fixes #933.
---
result/schematron/cve-2025-49794_0.err | 2 +
result/schematron/cve-2025-49796_0.err | 2 +
schematron.c | 67 ++++++++++++++------------
test/schematron/cve-2025-49794.sct | 10 ++++
test/schematron/cve-2025-49794_0.xml | 6 +++
test/schematron/cve-2025-49796.sct | 9 ++++
test/schematron/cve-2025-49796_0.xml | 3 ++
7 files changed, 67 insertions(+), 32 deletions(-)
create mode 100644 result/schematron/cve-2025-49794_0.err
create mode 100644 result/schematron/cve-2025-49796_0.err
create mode 100644 test/schematron/cve-2025-49794.sct
create mode 100644 test/schematron/cve-2025-49794_0.xml
create mode 100644 test/schematron/cve-2025-49796.sct
create mode 100644 test/schematron/cve-2025-49796_0.xml
diff --git a/result/schematron/cve-2025-49794_0.err b/result/schematron/cve-2025-49794_0.err
new file mode 100644
index 00000000..57752310
--- /dev/null
+++ b/result/schematron/cve-2025-49794_0.err
@@ -0,0 +1,2 @@
+./test/schematron/cve-2025-49794_0.xml:2: element boo0: schematron error : /librar0/boo0 line 2:
+./test/schematron/cve-2025-49794_0.xml fails to validate
diff --git a/result/schematron/cve-2025-49796_0.err b/result/schematron/cve-2025-49796_0.err
new file mode 100644
index 00000000..bf875ee0
--- /dev/null
+++ b/result/schematron/cve-2025-49796_0.err
@@ -0,0 +1,2 @@
+./test/schematron/cve-2025-49796_0.xml:2: element boo0: schematron error : /librar0/boo0 line 2:
+./test/schematron/cve-2025-49796_0.xml fails to validate
diff --git a/schematron.c b/schematron.c
index ddbb069b..0c7bc84a 100644
--- a/schematron.c
+++ b/schematron.c
@@ -1239,27 +1239,15 @@ exit:
* *
************************************************************************/
-static xmlNodePtr
+static xmlXPathObjectPtr
xmlSchematronGetNode(xmlSchematronValidCtxtPtr ctxt,
xmlNodePtr cur, const xmlChar *xpath) {
- xmlNodePtr node = NULL;
- xmlXPathObjectPtr ret;
-
if ((ctxt == NULL) || (cur == NULL) || (xpath == NULL))
return(NULL);
ctxt->xctxt->doc = cur->doc;
ctxt->xctxt->node = cur;
- ret = xmlXPathEval(xpath, ctxt->xctxt);
- if (ret == NULL)
- return(NULL);
-
- if ((ret->type == XPATH_NODESET) &&
- (ret->nodesetval != NULL) && (ret->nodesetval->nodeNr > 0))
- node = ret->nodesetval->nodeTab[0];
-
- xmlXPathFreeObject(ret);
- return(node);
+ return(xmlXPathEval(xpath, ctxt->xctxt));
}
/**
@@ -1301,28 +1289,43 @@ xmlSchematronFormatReport(xmlSchematronValidCtxtPtr ctxt,
child = test->children;
while (child != NULL) {
if ((child->type == XML_TEXT_NODE) ||
- (child->type == XML_CDATA_SECTION_NODE))
- ret = xmlStrcat(ret, child->content);
- else if (IS_SCHEMATRON(child, "name")) {
- xmlChar *path;
+ (child->type == XML_CDATA_SECTION_NODE))
+ ret = xmlStrcat(ret, child->content);
+ else if (IS_SCHEMATRON(child, "name")) {
+ xmlXPathObject *obj = NULL;
+ xmlChar *path;
path = xmlGetNoNsProp(child, BAD_CAST "path");
node = cur;
- if (path != NULL) {
- node = xmlSchematronGetNode(ctxt, cur, path);
- if (node == NULL)
- node = cur;
- xmlFree(path);
- }
-
- if ((node->ns == NULL) || (node->ns->prefix == NULL))
- ret = xmlStrcat(ret, node->name);
- else {
- ret = xmlStrcat(ret, node->ns->prefix);
- ret = xmlStrcat(ret, BAD_CAST ":");
- ret = xmlStrcat(ret, node->name);
- }
+ if (path != NULL) {
+ obj = xmlSchematronGetNode(ctxt, cur, path);
+ if ((obj != NULL) &&
+ (obj->type == XPATH_NODESET) &&
+ (obj->nodesetval != NULL) &&
+ (obj->nodesetval->nodeNr > 0))
+ node = obj->nodesetval->nodeTab[0];
+ xmlFree(path);
+ }
+
+ switch (node->type) {
+ case XML_ELEMENT_NODE:
+ case XML_ATTRIBUTE_NODE:
+ if ((node->ns == NULL) || (node->ns->prefix == NULL))
+ ret = xmlStrcat(ret, node->name);
+ else {
+ ret = xmlStrcat(ret, node->ns->prefix);
+ ret = xmlStrcat(ret, BAD_CAST ":");
+ ret = xmlStrcat(ret, node->name);
+ }
+ break;
+
+ /* TODO: handle other node types */
+ default:
+ break;
+ }
+
+ xmlXPathFreeObject(obj);
} else {
child = child->next;
continue;
diff --git a/test/schematron/cve-2025-49794.sct b/test/schematron/cve-2025-49794.sct
new file mode 100644
index 00000000..7fc9ee3d
--- /dev/null
+++ b/test/schematron/cve-2025-49794.sct
@@ -0,0 +1,10 @@
+<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron">
+ <sch:pattern id="">
+ <sch:rule context="boo0">
+ <sch:report test="not(0)">
+ <sch:name path="&#9;e|namespace::*|e"/>
+ </sch:report>
+ <sch:report test="0"></sch:report>
+ </sch:rule>
+ </sch:pattern>
+</sch:schema>
diff --git a/test/schematron/cve-2025-49794_0.xml b/test/schematron/cve-2025-49794_0.xml
new file mode 100644
index 00000000..debc64ba
--- /dev/null
+++ b/test/schematron/cve-2025-49794_0.xml
@@ -0,0 +1,6 @@
+<librar0>
+ <boo0 t="">
+ <author></author>
+ </boo0>
+ <ins></ins>
+</librar0>
diff --git a/test/schematron/cve-2025-49796.sct b/test/schematron/cve-2025-49796.sct
new file mode 100644
index 00000000..e9702d75
--- /dev/null
+++ b/test/schematron/cve-2025-49796.sct
@@ -0,0 +1,9 @@
+<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron">
+ <sch:pattern id="">
+ <sch:rule context="boo0">
+ <sch:report test="not(0)">
+ <sch:name path="/"/>
+ </sch:report>
+ </sch:rule>
+ </sch:pattern>
+</sch:schema>
diff --git a/test/schematron/cve-2025-49796_0.xml b/test/schematron/cve-2025-49796_0.xml
new file mode 100644
index 00000000..be33c4ec
--- /dev/null
+++ b/test/schematron/cve-2025-49796_0.xml
@@ -0,0 +1,3 @@
+<librar0>
+ <boo0/>
+</librar0>
--
2.49.0

View File

@ -1,49 +0,0 @@
From 1256dce1c2c928e1436a7e8bd8b40113099383c8 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Tue, 27 May 2025 12:53:17 +0200
Subject: [PATCH] tree: Fix integer overflow in xmlBuildQName
This issue affects memory safety and might receive a CVE ID later.
Fixes #926.
---
tree.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/tree.c b/tree.c
index 86afb7d6..3b0d0397 100644
--- a/tree.c
+++ b/tree.c
@@ -20,6 +20,7 @@
#include <string.h> /* for memset() only ! */
#include <stddef.h>
+#include <stdint.h>
#include <limits.h>
#ifdef HAVE_CTYPE_H
#include <ctype.h>
@@ -222,16 +223,18 @@ xmlGetParameterEntityFromDtd(const xmlDtd *dtd, const xmlChar *name) {
xmlChar *
xmlBuildQName(const xmlChar *ncname, const xmlChar *prefix,
xmlChar *memory, int len) {
- int lenn, lenp;
+ size_t lenn, lenp;
xmlChar *ret;
- if (ncname == NULL) return(NULL);
+ if ((ncname == NULL) || (len < 0)) return(NULL);
if (prefix == NULL) return((xmlChar *) ncname);
lenn = strlen((char *) ncname);
lenp = strlen((char *) prefix);
+ if (lenn >= SIZE_MAX - lenp - 1)
+ return(NULL);
- if ((memory == NULL) || (len < lenn + lenp + 2)) {
+ if ((memory == NULL) || ((size_t) len < lenn + lenp + 2)) {
ret = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2);
if (ret == NULL) {
xmlTreeErrMemory("building QName");
--
2.49.0

View File

@ -1,42 +0,0 @@
From a40db8fde759261b042138646da36c632a739f31 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Fri, 7 Apr 2023 11:49:27 +0200
Subject: [PATCH] [CVE-2023-29469] Hashing of empty dict strings isn't
deterministic
When hashing empty strings which aren't null-terminated,
xmlDictComputeFastKey could produce inconsistent results. This could
lead to various logic or memory errors, including double frees.
For consistency the seed is also taken into account, but this shouldn't
have an impact on security.
Found by OSS-Fuzz.
Fixes #510.
Incorporates change from commit
09a2dd453007f9c7205274623acdd73747c22d64.
---
dict.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/dict.c b/dict.c
index 0ef3718d..5e84cfca 100644
--- a/dict.c
+++ b/dict.c
@@ -444,8 +444,9 @@ static unsigned long
xmlDictComputeFastKey(const xmlChar *name, int namelen, int seed) {
unsigned long value = seed;
- if (name == NULL) return(0);
- value = *name;
+ if ((name == NULL) || (namelen <= 0))
+ return(value);
+ value += *name;
value <<= 5;
if (namelen > 10) {
value += name[namelen - 1];
--
2.41.0

View File

@ -1,29 +0,0 @@
From b9d4ab2fd6b7da380edab777a0414ef254804f0d Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Sat, 14 Oct 2023 22:45:54 +0200
Subject: [PATCH] [CVE-2024-25062] xmlreader: Don't expand XIncludes when
backtracking
Fixes a use-after-free if XML Reader if used with DTD validation and
XInclude expansion.
Fixes #604.
---
xmlreader.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/xmlreader.c b/xmlreader.c
index 34c4c6bc..8f2f9131 100644
--- a/xmlreader.c
+++ b/xmlreader.c
@@ -1511,6 +1511,7 @@ node_found:
* Handle XInclude if asked for
*/
if ((reader->xinclude) && (reader->node != NULL) &&
+ (reader->state != XML_TEXTREADER_BACKTRACK) &&
(reader->node->type == XML_ELEMENT_NODE) &&
(reader->node->ns != NULL) &&
((xmlStrEqual(reader->node->ns->href, XINCLUDE_NS)) ||
--
2.44.0

View File

@ -1,795 +0,0 @@
From 87786d6200ae1f5ac98d21f04d451e17ff25a216 Mon Sep 17 00:00:00 2001
From: David Kilzer <ddkilzer@apple.com>
Date: Mon, 23 Jun 2025 14:41:56 -0700
Subject: [PATCH] libxslt: heap-use-after-free in xmlFreeID caused by `atype`
corruption
* include/libxml/tree.h:
(XML_ATTR_CLEAR_ATYPE): Add.
(XML_ATTR_GET_ATYPE): Add.
(XML_ATTR_SET_ATYPE): Add.
(XML_NODE_ADD_EXTRA): Add.
(XML_NODE_CLEAR_EXTRA): Add.
(XML_NODE_GET_EXTRA): Add.
(XML_NODE_SET_EXTRA): Add.
(XML_DOC_ADD_PROPERTIES): Add.
(XML_DOC_CLEAR_PROPERTIES): Add.
(XML_DOC_GET_PROPERTIES): Add.
(XML_DOC_SET_PROPERTIES): Add.
- Add macros for accessing fields with upper bits that may be set by
libxslt.
* HTMLparser.c:
(htmlNewDocNoDtD):
* SAX2.c:
(xmlSAX2StartDocument):
(xmlSAX2EndDocument):
* parser.c:
(xmlParseEntityDecl):
(xmlParseExternalSubset):
(xmlParseReference):
(xmlCtxtParseDtd):
* runxmlconf.c:
(xmlconfTestInvalid):
(xmlconfTestValid):
* tree.c:
(xmlNewDoc):
(xmlFreeProp):
(xmlNodeSetDoc):
(xmlSetNsProp):
(xmlDOMWrapAdoptBranch):
* valid.c:
(xmlFreeID):
(xmlAddIDInternal):
(xmlValidateAttributeValueInternal):
(xmlValidateOneAttribute):
(xmlValidateRef):
* xmlreader.c:
(xmlTextReaderStartElement):
(xmlTextReaderStartElementNs):
(xmlTextReaderValidateEntity):
(xmlTextReaderRead):
(xmlTextReaderNext):
(xmlTextReaderIsEmptyElement):
(xmlTextReaderPreserve):
* xmlschemas.c:
(xmlSchemaPValAttrNodeID):
* xmlschemastypes.c:
(xmlSchemaValAtomicType):
- Adopt macros by renaming the struct fields, recompiling and fixing
compiler failures, then changing the struct field names back.
---
HTMLparser.c | 1 +
SAX2.c | 6 ++--
include/libxml/tree.h | 14 ++++++++-
parser.c | 8 ++---
runxmlconf.c | 4 +--
tree.c | 20 ++++++-------
valid.c | 68 +++++++++++++++++++++----------------------
xmlreader.c | 30 +++++++++----------
xmlschemas.c | 4 +--
xmlschemastypes.c | 12 ++++----
10 files changed, 90 insertions(+), 77 deletions(-)
diff --git a/HTMLparser.c b/HTMLparser.c
index e4f816e5..0ed96ad0 100644
--- a/HTMLparser.c
+++ b/HTMLparser.c
@@ -2335,6 +2335,7 @@ htmlNewDocNoDtD(const xmlChar *URI, const xmlChar *ExternalID) {
cur->refs = NULL;
cur->_private = NULL;
cur->charset = XML_CHAR_ENCODING_UTF8;
+ XML_DOC_SET_PROPERTIES(cur, XML_DOC_HTML | XML_DOC_USERBUILT);
cur->properties = XML_DOC_HTML | XML_DOC_USERBUILT;
if ((ExternalID != NULL) ||
(URI != NULL))
diff --git a/SAX2.c b/SAX2.c
index 0f261b7b..f283e5d1 100644
--- a/SAX2.c
+++ b/SAX2.c
@@ -999,7 +999,7 @@ xmlSAX2StartDocument(void *ctx)
xmlSAX2ErrMemory(ctxt, "xmlSAX2StartDocument");
return;
}
- ctxt->myDoc->properties = XML_DOC_HTML;
+ XML_DOC_SET_PROPERTIES(ctxt->myDoc, XML_DOC_HTML);
ctxt->myDoc->parseFlags = ctxt->options;
#else
xmlGenericError(xmlGenericErrorContext,
@@ -1012,9 +1012,9 @@ xmlSAX2StartDocument(void *ctx)
} else {
doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
if (doc != NULL) {
- doc->properties = 0;
+ XML_DOC_CLEAR_PROPERTIES(doc);
if (ctxt->options & XML_PARSE_OLD10)
- doc->properties |= XML_DOC_OLD10;
+ XML_DOC_ADD_PROPERTIES(doc, XML_DOC_OLD10);
doc->parseFlags = ctxt->options;
if (ctxt->encoding != NULL)
doc->encoding = xmlStrdup(ctxt->encoding);
diff --git a/include/libxml/tree.h b/include/libxml/tree.h
index 4a9b3bc6..91ea0602 100644
--- a/include/libxml/tree.h
+++ b/include/libxml/tree.h
@@ -365,7 +365,6 @@ struct _xmlElement {
#endif
};
-
/**
* XML_LOCAL_NAMESPACE:
*
@@ -446,6 +445,10 @@ struct _xmlAttr {
void *psvi; /* for type/PSVI informations */
};
+#define XML_ATTR_CLEAR_ATYPE(attr) (((attr)->atype) = 0)
+#define XML_ATTR_GET_ATYPE(attr) (((attr)->atype) & ~(15U << 27))
+#define XML_ATTR_SET_ATYPE(attr, type) ((attr)->atype = ((((attr)->atype) & (15U << 27)) | ((type) & ~(15U << 27))))
+
/**
* xmlID:
*
@@ -507,6 +510,11 @@ struct _xmlNode {
unsigned short extra; /* extra data for XPath/XSLT */
};
+#define XML_NODE_ADD_EXTRA(node, type) ((node)->extra |= ((type) & ~(15U << 12)))
+#define XML_NODE_CLEAR_EXTRA(node) (((node)->extra) = 0)
+#define XML_NODE_GET_EXTRA(node) (((node)->extra) & ~(15U << 12))
+#define XML_NODE_SET_EXTRA(node, type) ((node)->extra = ((((node)->extra) & (15U << 12)) | ((type) & ~(15U << 12))))
+
/**
* XML_GET_CONTENT:
*
@@ -585,6 +593,10 @@ struct _xmlDoc {
set at the end of parsing */
};
+#define XML_DOC_ADD_PROPERTIES(doc, type) ((doc)->properties |= ((type) & ~(15U << 27)))
+#define XML_DOC_CLEAR_PROPERTIES(doc) (((doc)->properties) = 0)
+#define XML_DOC_GET_PROPERTIES(doc) (((doc)->properties) & ~(15U << 27))
+#define XML_DOC_SET_PROPERTIES(doc, type) ((doc)->properties = ((((doc)->properties) & (15U << 27)) | ((type) & ~(15U << 27))))
typedef struct _xmlDOMWrapCtxt xmlDOMWrapCtxt;
typedef xmlDOMWrapCtxt *xmlDOMWrapCtxtPtr;
diff --git a/parser.c b/parser.c
index 1c5e036e..874cef74 100644
--- a/parser.c
+++ b/parser.c
@@ -5446,7 +5446,7 @@ xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
xmlErrMemory(ctxt, "New Doc failed");
return;
}
- ctxt->myDoc->properties = XML_DOC_INTERNAL;
+ XML_DOC_SET_PROPERTIES(ctxt->myDoc, XML_DOC_INTERNAL);
}
if (ctxt->myDoc->intSubset == NULL)
ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc,
@@ -5517,7 +5517,7 @@ xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
xmlErrMemory(ctxt, "New Doc failed");
return;
}
- ctxt->myDoc->properties = XML_DOC_INTERNAL;
+ XML_DOC_SET_PROPERTIES(ctxt->myDoc, XML_DOC_INTERNAL);
}
if (ctxt->myDoc->intSubset == NULL)
@@ -6953,7 +6953,7 @@ xmlParseExternalSubset(xmlParserCtxtPtr ctxt, const xmlChar *ExternalID,
xmlErrMemory(ctxt, "New Doc failed");
return;
}
- ctxt->myDoc->properties = XML_DOC_INTERNAL;
+ XML_DOC_SET_PROPERTIES(ctxt->myDoc, XML_DOC_INTERNAL);
}
if ((ctxt->myDoc != NULL) && (ctxt->myDoc->intSubset == NULL))
xmlCreateIntSubset(ctxt->myDoc, NULL, ExternalID, SystemID);
@@ -7335,7 +7335,7 @@ xmlParseReference(xmlParserCtxtPtr ctxt) {
(nw != NULL) &&
(nw->type == XML_ELEMENT_NODE) &&
(nw->children == NULL))
- nw->extra = 1;
+ XML_NODE_SET_EXTRA(nw, 1);
break;
}
diff --git a/runxmlconf.c b/runxmlconf.c
index cef20f48..e233eaf8 100644
--- a/runxmlconf.c
+++ b/runxmlconf.c
@@ -197,7 +197,7 @@ xmlconfTestInvalid(const char *id, const char *filename, int options) {
id, filename);
} else {
/* invalidity should be reported both in the context and in the document */
- if ((ctxt->valid != 0) || (doc->properties & XML_DOC_DTDVALID)) {
+ if ((ctxt->valid != 0) || (XML_DOC_GET_PROPERTIES(doc) & XML_DOC_DTDVALID)) {
test_log("test %s : %s failed to detect invalid document\n",
id, filename);
nb_errors++;
@@ -229,7 +229,7 @@ xmlconfTestValid(const char *id, const char *filename, int options) {
ret = 0;
} else {
/* validity should be reported both in the context and in the document */
- if ((ctxt->valid == 0) || ((doc->properties & XML_DOC_DTDVALID) == 0)) {
+ if ((ctxt->valid == 0) || ((XML_DOC_GET_PROPERTIES(doc) & XML_DOC_DTDVALID) == 0)) {
test_log("test %s : %s failed to validate a valid document\n",
id, filename);
nb_errors++;
diff --git a/tree.c b/tree.c
index 86a8da79..f701baa6 100644
--- a/tree.c
+++ b/tree.c
@@ -1186,7 +1186,7 @@ xmlNewDoc(const xmlChar *version) {
cur->compression = -1; /* not initialized */
cur->doc = cur;
cur->parseFlags = 0;
- cur->properties = XML_DOC_USERBUILT;
+ XML_DOC_SET_PROPERTIES(cur, XML_DOC_USERBUILT);
/*
* The in memory encoding is always UTF8
* This field will never change and would
@@ -2091,7 +2091,7 @@ xmlFreeProp(xmlAttrPtr cur) {
xmlDeregisterNodeDefaultValue((xmlNodePtr)cur);
/* Check for ID removal -> leading to invalid references ! */
- if ((cur->doc != NULL) && (cur->atype == XML_ATTRIBUTE_ID)) {
+ if ((cur->doc != NULL) && (XML_ATTR_GET_ATYPE(cur) == XML_ATTRIBUTE_ID)) {
xmlRemoveID(cur->doc, cur);
}
if (cur->children != NULL) xmlFreeNodeList(cur->children);
@@ -2810,7 +2810,7 @@ xmlSetTreeDoc(xmlNodePtr tree, xmlDocPtr doc) {
if(tree->type == XML_ELEMENT_NODE) {
prop = tree->properties;
while (prop != NULL) {
- if (prop->atype == XML_ATTRIBUTE_ID) {
+ if (XML_ATTR_GET_ATYPE(prop) == XML_ATTRIBUTE_ID) {
xmlRemoveID(tree->doc, prop);
}
@@ -6882,9 +6882,9 @@ xmlSetNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name,
/*
* Modify the attribute's value.
*/
- if (prop->atype == XML_ATTRIBUTE_ID) {
+ if (XML_ATTR_GET_ATYPE(prop) == XML_ATTRIBUTE_ID) {
xmlRemoveID(node->doc, prop);
- prop->atype = XML_ATTRIBUTE_ID;
+ XML_ATTR_SET_ATYPE(prop, XML_ATTRIBUTE_ID);
}
if (prop->children != NULL)
xmlFreeNodeList(prop->children);
@@ -6910,7 +6910,7 @@ xmlSetNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name,
tmp = tmp->next;
}
}
- if (prop->atype == XML_ATTRIBUTE_ID)
+ if (XML_ATTR_GET_ATYPE(prop) == XML_ATTRIBUTE_ID)
xmlAddID(NULL, node->doc, value, prop);
return(prop);
}
@@ -9200,7 +9200,7 @@ ns_end:
if (cur->type == XML_ELEMENT_NODE) {
cur->psvi = NULL;
cur->line = 0;
- cur->extra = 0;
+ XML_NODE_CLEAR_EXTRA(cur);
/*
* Walk attributes.
*/
@@ -9216,11 +9216,11 @@ ns_end:
* Attributes.
*/
if ((sourceDoc != NULL) &&
- (((xmlAttrPtr) cur)->atype == XML_ATTRIBUTE_ID))
+ (XML_ATTR_GET_ATYPE((xmlAttrPtr) cur) == XML_ATTRIBUTE_ID))
{
xmlRemoveID(sourceDoc, (xmlAttrPtr) cur);
}
- ((xmlAttrPtr) cur)->atype = 0;
+ XML_ATTR_CLEAR_ATYPE((xmlAttrPtr) cur);
((xmlAttrPtr) cur)->psvi = NULL;
}
break;
@@ -9940,7 +9940,7 @@ xmlDOMWrapAdoptAttr(xmlDOMWrapCtxtPtr ctxt,
}
XML_TREE_ADOPT_STR(attr->name);
- attr->atype = 0;
+ XML_ATTR_CLEAR_ATYPE(attr);
attr->psvi = NULL;
/*
* Walk content.
diff --git a/valid.c b/valid.c
index a64b96be..ff293750 100644
--- a/valid.c
+++ b/valid.c
@@ -1856,7 +1856,7 @@ xmlScanIDAttributeDecl(xmlValidCtxtPtr ctxt, xmlElementPtr elem, int err) {
if (elem == NULL) return(0);
cur = elem->attributes;
while (cur != NULL) {
- if (cur->atype == XML_ATTRIBUTE_ID) {
+ if (XML_ATTR_GET_ATYPE(cur) == XML_ATTRIBUTE_ID) {
ret ++;
if ((ret > 1) && (err))
xmlErrValidNode(ctxt, (xmlNodePtr) elem, XML_DTD_MULTIPLE_ID,
@@ -2224,7 +2224,7 @@ xmlDumpAttributeDecl(xmlBufferPtr buf, xmlAttributePtr attr) {
xmlBufferWriteChar(buf, ":");
}
xmlBufferWriteCHAR(buf, attr->name);
- switch (attr->atype) {
+ switch (XML_ATTR_GET_ATYPE(attr)) {
case XML_ATTRIBUTE_CDATA:
xmlBufferWriteChar(buf, " CDATA");
break;
@@ -2649,7 +2649,7 @@ xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
return(NULL);
}
if (attr != NULL)
- attr->atype = XML_ATTRIBUTE_ID;
+ XML_ATTR_SET_ATYPE(attr, XML_ATTRIBUTE_ID);
return(ret);
}
@@ -2723,7 +2723,7 @@ xmlIsID(xmlDocPtr doc, xmlNodePtr elem, xmlAttrPtr attr) {
if ((fullelemname != felem) && (fullelemname != elem->name))
xmlFree(fullelemname);
- if ((attrDecl != NULL) && (attrDecl->atype == XML_ATTRIBUTE_ID))
+ if ((attrDecl != NULL) && (XML_ATTR_GET_ATYPE(attrDecl) == XML_ATTRIBUTE_ID))
return(1);
}
return(0);
@@ -2763,7 +2763,7 @@ xmlRemoveID(xmlDocPtr doc, xmlAttrPtr attr) {
xmlHashRemoveEntry(table, ID, (xmlHashDeallocator) xmlFreeID);
xmlFree(ID);
- attr->atype = 0;
+ XML_ATTR_CLEAR_ATYPE(attr);
return(0);
}
@@ -3041,8 +3041,8 @@ xmlIsRef(xmlDocPtr doc, xmlNodePtr elem, xmlAttrPtr attr) {
elem->name, attr->name);
if ((attrDecl != NULL) &&
- (attrDecl->atype == XML_ATTRIBUTE_IDREF ||
- attrDecl->atype == XML_ATTRIBUTE_IDREFS))
+ (XML_ATTR_GET_ATYPE(attrDecl) == XML_ATTRIBUTE_IDREF ||
+ XML_ATTR_GET_ATYPE(attrDecl) == XML_ATTRIBUTE_IDREFS))
return(1);
}
return(0);
@@ -3417,7 +3417,7 @@ xmlIsMixedElement(xmlDocPtr doc, const xmlChar *name) {
static int
xmlIsDocNameStartChar(xmlDocPtr doc, int c) {
- if ((doc == NULL) || (doc->properties & XML_DOC_OLD10) == 0) {
+ if ((doc == NULL) || (XML_DOC_GET_PROPERTIES(doc) & XML_DOC_OLD10) == 0) {
/*
* Use the new checks of production [4] [4a] amd [5] of the
* Update 5 of XML-1.0
@@ -3447,7 +3447,7 @@ xmlIsDocNameStartChar(xmlDocPtr doc, int c) {
static int
xmlIsDocNameChar(xmlDocPtr doc, int c) {
- if ((doc == NULL) || (doc->properties & XML_DOC_OLD10) == 0) {
+ if ((doc == NULL) || (XML_DOC_GET_PROPERTIES(doc) & XML_DOC_OLD10) == 0) {
/*
* Use the new checks of production [4] [4a] amd [5] of the
* Update 5 of XML-1.0
@@ -3998,7 +3998,7 @@ xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
if (attrDecl == NULL)
return(NULL);
- if (attrDecl->atype == XML_ATTRIBUTE_CDATA)
+ if (XML_ATTR_GET_ATYPE(attrDecl) == XML_ATTRIBUTE_CDATA)
return(NULL);
ret = xmlStrdup(value);
@@ -4073,7 +4073,7 @@ xmlValidNormalizeAttributeValue(xmlDocPtr doc, xmlNodePtr elem,
if (attrDecl == NULL)
return(NULL);
- if (attrDecl->atype == XML_ATTRIBUTE_CDATA)
+ if (XML_ATTR_GET_ATYPE(attrDecl) == XML_ATTRIBUTE_CDATA)
return(NULL);
ret = xmlStrdup(value);
@@ -4098,7 +4098,7 @@ xmlValidNormalizeAttributeValue(xmlDocPtr doc, xmlNodePtr elem,
static void
xmlValidateAttributeIdCallback(xmlAttributePtr attr, int *count,
const xmlChar* name ATTRIBUTE_UNUSED) {
- if (attr->atype == XML_ATTRIBUTE_ID) (*count)++;
+ if (XML_ATTR_GET_ATYPE(attr) == XML_ATTRIBUTE_ID) (*count)++;
}
/**
@@ -4130,7 +4130,7 @@ xmlValidateAttributeDecl(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
/* Attribute Default Legal */
/* Enumeration */
if (attr->defaultValue != NULL) {
- val = xmlValidateAttributeValueInternal(doc, attr->atype,
+ val = xmlValidateAttributeValueInternal(doc, XML_ATTR_GET_ATYPE(attr),
attr->defaultValue);
if (val == 0) {
xmlErrValidNode(ctxt, (xmlNodePtr) attr, XML_DTD_ATTRIBUTE_DEFAULT,
@@ -4141,7 +4141,7 @@ xmlValidateAttributeDecl(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
}
/* ID Attribute Default */
- if ((attr->atype == XML_ATTRIBUTE_ID)&&
+ if ((XML_ATTR_GET_ATYPE(attr) == XML_ATTRIBUTE_ID)&&
(attr->def != XML_ATTRIBUTE_IMPLIED) &&
(attr->def != XML_ATTRIBUTE_REQUIRED)) {
xmlErrValidNode(ctxt, (xmlNodePtr) attr, XML_DTD_ID_FIXED,
@@ -4151,7 +4151,7 @@ xmlValidateAttributeDecl(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
}
/* One ID per Element Type */
- if (attr->atype == XML_ATTRIBUTE_ID) {
+ if (XML_ATTR_GET_ATYPE(attr) == XML_ATTRIBUTE_ID) {
int nbId;
/* the trick is that we parse DtD as their own internal subset */
@@ -4410,9 +4410,9 @@ xmlValidateOneAttribute(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
attr->name, elem->name, NULL);
return(0);
}
- attr->atype = attrDecl->atype;
+ XML_ATTR_SET_ATYPE(attr, attrDecl->atype);
- val = xmlValidateAttributeValueInternal(doc, attrDecl->atype, value);
+ val = xmlValidateAttributeValueInternal(doc, XML_ATTR_GET_ATYPE(attrDecl), value);
if (val == 0) {
xmlErrValidNode(ctxt, elem, XML_DTD_ATTRIBUTE_VALUE,
"Syntax of value for attribute %s of %s is not valid\n",
@@ -4431,19 +4431,19 @@ xmlValidateOneAttribute(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
}
/* Validity Constraint: ID uniqueness */
- if (attrDecl->atype == XML_ATTRIBUTE_ID) {
+ if (XML_ATTR_GET_ATYPE(attrDecl) == XML_ATTRIBUTE_ID) {
if (xmlAddID(ctxt, doc, value, attr) == NULL)
ret = 0;
}
- if ((attrDecl->atype == XML_ATTRIBUTE_IDREF) ||
- (attrDecl->atype == XML_ATTRIBUTE_IDREFS)) {
+ if ((XML_ATTR_GET_ATYPE(attrDecl) == XML_ATTRIBUTE_IDREF) ||
+ (XML_ATTR_GET_ATYPE(attrDecl) == XML_ATTRIBUTE_IDREFS)) {
if (xmlAddRef(ctxt, doc, value, attr) == NULL)
ret = 0;
}
/* Validity Constraint: Notation Attributes */
- if (attrDecl->atype == XML_ATTRIBUTE_NOTATION) {
+ if (XML_ATTR_GET_ATYPE(attrDecl) == XML_ATTRIBUTE_NOTATION) {
xmlEnumerationPtr tree = attrDecl->tree;
xmlNotationPtr nota;
@@ -4473,7 +4473,7 @@ xmlValidateOneAttribute(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
}
/* Validity Constraint: Enumeration */
- if (attrDecl->atype == XML_ATTRIBUTE_ENUMERATION) {
+ if (XML_ATTR_GET_ATYPE(attrDecl) == XML_ATTRIBUTE_ENUMERATION) {
xmlEnumerationPtr tree = attrDecl->tree;
while (tree != NULL) {
if (xmlStrEqual(tree->name, value)) break;
@@ -4498,7 +4498,7 @@ xmlValidateOneAttribute(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
/* Extra check for the attribute value */
ret &= xmlValidateAttributeValue2(ctxt, doc, attr->name,
- attrDecl->atype, value);
+ XML_ATTR_GET_ATYPE(attrDecl), value);
return(ret);
}
@@ -4597,7 +4597,7 @@ xmlNodePtr elem, const xmlChar *prefix, xmlNsPtr ns, const xmlChar *value) {
return(0);
}
- val = xmlValidateAttributeValueInternal(doc, attrDecl->atype, value);
+ val = xmlValidateAttributeValueInternal(doc, XML_ATTR_GET_ATYPE(attrDecl), value);
if (val == 0) {
if (ns->prefix != NULL) {
xmlErrValidNode(ctxt, elem, XML_DTD_INVALID_DEFAULT,
@@ -4647,7 +4647,7 @@ xmlNodePtr elem, const xmlChar *prefix, xmlNsPtr ns, const xmlChar *value) {
#endif
/* Validity Constraint: Notation Attributes */
- if (attrDecl->atype == XML_ATTRIBUTE_NOTATION) {
+ if (XML_ATTR_GET_ATYPE(attrDecl) == XML_ATTRIBUTE_NOTATION) {
xmlEnumerationPtr tree = attrDecl->tree;
xmlNotationPtr nota;
@@ -4689,7 +4689,7 @@ xmlNodePtr elem, const xmlChar *prefix, xmlNsPtr ns, const xmlChar *value) {
}
/* Validity Constraint: Enumeration */
- if (attrDecl->atype == XML_ATTRIBUTE_ENUMERATION) {
+ if (XML_ATTR_GET_ATYPE(attrDecl) == XML_ATTRIBUTE_ENUMERATION) {
xmlEnumerationPtr tree = attrDecl->tree;
while (tree != NULL) {
if (xmlStrEqual(tree->name, value)) break;
@@ -4727,10 +4727,10 @@ xmlNodePtr elem, const xmlChar *prefix, xmlNsPtr ns, const xmlChar *value) {
/* Extra check for the attribute value */
if (ns->prefix != NULL) {
ret &= xmlValidateAttributeValue2(ctxt, doc, ns->prefix,
- attrDecl->atype, value);
+ XML_ATTR_GET_ATYPE(attrDecl), value);
} else {
ret &= xmlValidateAttributeValue2(ctxt, doc, BAD_CAST "xmlns",
- attrDecl->atype, value);
+ XML_ATTR_GET_ATYPE(attrDecl), value);
}
return(ret);
@@ -6483,7 +6483,7 @@ xmlValidateRef(xmlRefPtr ref, xmlValidCtxtPtr ctxt,
while (IS_BLANK_CH(*cur)) cur++;
}
xmlFree(dup);
- } else if (attr->atype == XML_ATTRIBUTE_IDREF) {
+ } else if (XML_ATTR_GET_ATYPE(attr) == XML_ATTRIBUTE_IDREF) {
id = xmlGetID(ctxt->doc, name);
if (id == NULL) {
xmlErrValidNode(ctxt, attr->parent, XML_DTD_UNKNOWN_ID,
@@ -6491,7 +6491,7 @@ xmlValidateRef(xmlRefPtr ref, xmlValidCtxtPtr ctxt,
attr->name, name, NULL);
ctxt->valid = 0;
}
- } else if (attr->atype == XML_ATTRIBUTE_IDREFS) {
+ } else if (XML_ATTR_GET_ATYPE(attr) == XML_ATTRIBUTE_IDREFS) {
xmlChar *dup, *str = NULL, *cur, save;
dup = xmlStrdup(name);
@@ -6686,7 +6686,7 @@ xmlValidateAttributeCallback(xmlAttributePtr cur, xmlValidCtxtPtr ctxt,
if (cur == NULL)
return;
- switch (cur->atype) {
+ switch (XML_ATTR_GET_ATYPE(cur)) {
case XML_ATTRIBUTE_CDATA:
case XML_ATTRIBUTE_ID:
case XML_ATTRIBUTE_IDREF :
@@ -6701,7 +6701,7 @@ xmlValidateAttributeCallback(xmlAttributePtr cur, xmlValidCtxtPtr ctxt,
if (cur->defaultValue != NULL) {
ret = xmlValidateAttributeValue2(ctxt, ctxt->doc, cur->name,
- cur->atype, cur->defaultValue);
+ XML_ATTR_GET_ATYPE(cur), cur->defaultValue);
if ((ret == 0) && (ctxt->valid == 1))
ctxt->valid = 0;
}
@@ -6709,14 +6709,14 @@ xmlValidateAttributeCallback(xmlAttributePtr cur, xmlValidCtxtPtr ctxt,
xmlEnumerationPtr tree = cur->tree;
while (tree != NULL) {
ret = xmlValidateAttributeValue2(ctxt, ctxt->doc,
- cur->name, cur->atype, tree->name);
+ cur->name, XML_ATTR_GET_ATYPE(cur), tree->name);
if ((ret == 0) && (ctxt->valid == 1))
ctxt->valid = 0;
tree = tree->next;
}
}
}
- if (cur->atype == XML_ATTRIBUTE_NOTATION) {
+ if (XML_ATTR_GET_ATYPE(cur) == XML_ATTRIBUTE_NOTATION) {
doc = cur->doc;
if (cur->elem == NULL) {
xmlErrValid(ctxt, XML_ERR_INTERNAL_ERROR,
diff --git a/xmlreader.c b/xmlreader.c
index 34c4c6bc..1c584311 100644
--- a/xmlreader.c
+++ b/xmlreader.c
@@ -669,7 +669,7 @@ xmlTextReaderStartElement(void *ctx, const xmlChar *fullname,
if ((ctxt->node != NULL) && (ctxt->input != NULL) &&
(ctxt->input->cur != NULL) && (ctxt->input->cur[0] == '/') &&
(ctxt->input->cur[1] == '>'))
- ctxt->node->extra = NODE_IS_EMPTY;
+ XML_NODE_SET_EXTRA(ctxt->node, NODE_IS_EMPTY);
}
if (reader != NULL)
reader->state = XML_TEXTREADER_ELEMENT;
@@ -734,7 +734,7 @@ xmlTextReaderStartElementNs(void *ctx,
if ((ctxt->node != NULL) && (ctxt->input != NULL) &&
(ctxt->input->cur != NULL) && (ctxt->input->cur[0] == '/') &&
(ctxt->input->cur[1] == '>'))
- ctxt->node->extra = NODE_IS_EMPTY;
+ XML_NODE_SET_EXTRA(ctxt->node, NODE_IS_EMPTY);
}
if (reader != NULL)
reader->state = XML_TEXTREADER_ELEMENT;
@@ -1143,7 +1143,7 @@ xmlTextReaderValidateEntity(xmlTextReaderPtr reader) {
xmlNodePtr tmp;
if (reader->entNr == 0) {
while ((tmp = node->last) != NULL) {
- if ((tmp->extra & NODE_IS_PRESERVED) == 0) {
+ if ((XML_NODE_GET_EXTRA(tmp) & NODE_IS_PRESERVED) == 0) {
xmlUnlinkNode(tmp);
xmlTextReaderFreeNode(reader, tmp);
} else
@@ -1394,7 +1394,7 @@ get_next_node:
if ((oldstate == XML_TEXTREADER_ELEMENT) &&
(reader->node->type == XML_ELEMENT_NODE) &&
(reader->node->children == NULL) &&
- ((reader->node->extra & NODE_IS_EMPTY) == 0)
+ ((XML_NODE_GET_EXTRA(reader->node) & NODE_IS_EMPTY) == 0)
#ifdef LIBXML_XINCLUDE_ENABLED
&& (reader->in_xinclude <= 0)
#endif
@@ -1408,7 +1408,7 @@ get_next_node:
xmlTextReaderValidatePop(reader);
#endif /* LIBXML_REGEXP_ENABLED */
if ((reader->preserves > 0) &&
- (reader->node->extra & NODE_IS_SPRESERVED))
+ (XML_NODE_GET_EXTRA(reader->node) & NODE_IS_SPRESERVED))
reader->preserves--;
reader->node = reader->node->next;
reader->state = XML_TEXTREADER_ELEMENT;
@@ -1424,7 +1424,7 @@ get_next_node:
(reader->node->prev != NULL) &&
(reader->node->prev->type != XML_DTD_NODE)) {
xmlNodePtr tmp = reader->node->prev;
- if ((tmp->extra & NODE_IS_PRESERVED) == 0) {
+ if ((XML_NODE_GET_EXTRA(tmp) & NODE_IS_PRESERVED) == 0) {
xmlUnlinkNode(tmp);
xmlTextReaderFreeNode(reader, tmp);
}
@@ -1435,7 +1435,7 @@ get_next_node:
if ((oldstate == XML_TEXTREADER_ELEMENT) &&
(reader->node->type == XML_ELEMENT_NODE) &&
(reader->node->children == NULL) &&
- ((reader->node->extra & NODE_IS_EMPTY) == 0)) {;
+ ((XML_NODE_GET_EXTRA(reader->node) & NODE_IS_EMPTY) == 0)) {;
reader->state = XML_TEXTREADER_END;
goto node_found;
}
@@ -1444,7 +1444,7 @@ get_next_node:
xmlTextReaderValidatePop(reader);
#endif /* LIBXML_REGEXP_ENABLED */
if ((reader->preserves > 0) &&
- (reader->node->extra & NODE_IS_SPRESERVED))
+ (XML_NODE_GET_EXTRA(reader->node) & NODE_IS_SPRESERVED))
reader->preserves--;
reader->node = reader->node->parent;
if ((reader->node == NULL) ||
@@ -1471,7 +1471,7 @@ get_next_node:
#endif
(reader->entNr == 0) &&
(oldnode->type != XML_DTD_NODE) &&
- ((oldnode->extra & NODE_IS_PRESERVED) == 0)) {
+ ((XML_NODE_GET_EXTRA(oldnode) & NODE_IS_PRESERVED) == 0)) {
xmlUnlinkNode(oldnode);
xmlTextReaderFreeNode(reader, oldnode);
}
@@ -1484,7 +1484,7 @@ get_next_node:
#endif
(reader->entNr == 0) &&
(reader->node->last != NULL) &&
- ((reader->node->last->extra & NODE_IS_PRESERVED) == 0)) {
+ ((XML_NODE_GET_EXTRA(reader->node->last) & NODE_IS_PRESERVED) == 0)) {
xmlNodePtr tmp = reader->node->last;
xmlUnlinkNode(tmp);
xmlTextReaderFreeNode(reader, tmp);
@@ -1674,7 +1674,7 @@ xmlTextReaderNext(xmlTextReaderPtr reader) {
return(xmlTextReaderRead(reader));
if (reader->state == XML_TEXTREADER_END || reader->state == XML_TEXTREADER_BACKTRACK)
return(xmlTextReaderRead(reader));
- if (cur->extra & NODE_IS_EMPTY)
+ if (XML_NODE_GET_EXTRA(cur) & NODE_IS_EMPTY)
return(xmlTextReaderRead(reader));
do {
ret = xmlTextReaderRead(reader);
@@ -3093,7 +3093,7 @@ xmlTextReaderIsEmptyElement(xmlTextReaderPtr reader) {
if (reader->in_xinclude > 0)
return(1);
#endif
- return((reader->node->extra & NODE_IS_EMPTY) != 0);
+ return((XML_NODE_GET_EXTRA(reader->node) & NODE_IS_EMPTY) != 0);
}
/**
@@ -3957,15 +3957,15 @@ xmlTextReaderPreserve(xmlTextReaderPtr reader) {
return(NULL);
if ((cur->type != XML_DOCUMENT_NODE) && (cur->type != XML_DTD_NODE)) {
- cur->extra |= NODE_IS_PRESERVED;
- cur->extra |= NODE_IS_SPRESERVED;
+ XML_NODE_ADD_EXTRA(cur, NODE_IS_PRESERVED);
+ XML_NODE_ADD_EXTRA(cur, NODE_IS_SPRESERVED);
}
reader->preserves++;
parent = cur->parent;;
while (parent != NULL) {
if (parent->type == XML_ELEMENT_NODE)
- parent->extra |= NODE_IS_PRESERVED;
+ XML_NODE_ADD_EXTRA(parent, NODE_IS_PRESERVED);
parent = parent->parent;
}
return(cur);
diff --git a/xmlschemas.c b/xmlschemas.c
index 05a12e0b..5d61deb2 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -5969,7 +5969,7 @@ xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr)
/*
* NOTE: the IDness might have already be declared in the DTD
*/
- if (attr->atype != XML_ATTRIBUTE_ID) {
+ if (XML_ATTR_GET_ATYPE(attr) != XML_ATTRIBUTE_ID) {
xmlIDPtr res;
xmlChar *strip;
@@ -5992,7 +5992,7 @@ xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr)
NULL, NULL, "Duplicate value '%s' of simple "
"type 'xs:ID'", value, NULL);
} else
- attr->atype = XML_ATTRIBUTE_ID;
+ XML_ATTR_SET_ATYPE(attr, XML_ATTRIBUTE_ID);
}
} else if (ret > 0) {
ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
diff --git a/xmlschemastypes.c b/xmlschemastypes.c
index c6c93659..a85475db 100644
--- a/xmlschemastypes.c
+++ b/xmlschemastypes.c
@@ -2760,7 +2760,7 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar * value,
/*
* NOTE: the IDness might have already be declared in the DTD
*/
- if (attr->atype != XML_ATTRIBUTE_ID) {
+ if (XML_ATTR_GET_ATYPE(attr) != XML_ATTRIBUTE_ID) {
xmlIDPtr res;
xmlChar *strip;
@@ -2773,7 +2773,7 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar * value,
if (res == NULL) {
ret = 2;
} else {
- attr->atype = XML_ATTRIBUTE_ID;
+ XML_ATTR_SET_ATYPE(attr, XML_ATTRIBUTE_ID);
}
}
}
@@ -2798,7 +2798,7 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar * value,
xmlFree(strip);
} else
xmlAddRef(NULL, node->doc, value, attr);
- attr->atype = XML_ATTRIBUTE_IDREF;
+ XML_ATTR_SET_ATYPE(attr, XML_ATTRIBUTE_IDREF);
}
goto done;
case XML_SCHEMAS_IDREFS:
@@ -2812,7 +2812,7 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar * value,
(node->type == XML_ATTRIBUTE_NODE)) {
xmlAttrPtr attr = (xmlAttrPtr) node;
- attr->atype = XML_ATTRIBUTE_IDREFS;
+ XML_ATTR_SET_ATYPE(attr, XML_ATTRIBUTE_IDREFS);
}
goto done;
case XML_SCHEMAS_ENTITY:{
@@ -2843,7 +2843,7 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar * value,
(node->type == XML_ATTRIBUTE_NODE)) {
xmlAttrPtr attr = (xmlAttrPtr) node;
- attr->atype = XML_ATTRIBUTE_ENTITY;
+ XML_ATTR_SET_ATYPE(attr, XML_ATTRIBUTE_ENTITY);
}
goto done;
}
@@ -2860,7 +2860,7 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar * value,
(node->type == XML_ATTRIBUTE_NODE)) {
xmlAttrPtr attr = (xmlAttrPtr) node;
- attr->atype = XML_ATTRIBUTE_ENTITIES;
+ XML_ATTR_SET_ATYPE(attr, XML_ATTRIBUTE_ENTITIES);
}
goto done;
case XML_SCHEMAS_NOTATION:{
--
2.49.0

View File

@ -1,56 +0,0 @@
From 40e00bc5174ab61036c893078123467144b05a4a Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Mon, 14 Oct 2019 16:56:59 +0200
Subject: [PATCH] Fix integer overflow when counting written bytes
Check for integer overflow when updating the `written` member of
struct xmlOutputBuffer in xmlIO.c.
Closes #112. Resolves !54 and !55.
---
xmlIO.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/xmlIO.c b/xmlIO.c
index 2a1e2cb08..752d5e0a0 100644
--- a/xmlIO.c
+++ b/xmlIO.c
@@ -3413,7 +3413,10 @@ xmlOutputBufferWrite(xmlOutputBufferPtr out, int len, const char *buf) {
out->error = XML_IO_WRITE;
return(ret);
}
- out->written += ret;
+ if (out->written > INT_MAX - ret)
+ out->written = INT_MAX;
+ else
+ out->written += ret;
}
written += nbchars;
} while (len > 0);
@@ -3609,7 +3612,10 @@ xmlOutputBufferWriteEscape(xmlOutputBufferPtr out, const xmlChar *str,
out->error = XML_IO_WRITE;
return(ret);
}
- out->written += ret;
+ if (out->written > INT_MAX - ret)
+ out->written = INT_MAX;
+ else
+ out->written += ret;
} else if (xmlBufAvail(out->buffer) < MINLEN) {
xmlBufGrow(out->buffer, MINLEN);
}
@@ -3703,7 +3709,10 @@ xmlOutputBufferFlush(xmlOutputBufferPtr out) {
out->error = XML_IO_FLUSH;
return(ret);
}
- out->written += ret;
+ if (out->written > INT_MAX - ret)
+ out->written = INT_MAX;
+ else
+ out->written += ret;
#ifdef DEBUG_INPUT
xmlGenericError(xmlGenericErrorContext,
--
GitLab

View File

@ -7,7 +7,7 @@
Name: libxml2
Version: 2.9.7
Release: 21%{?dist}.3
Release: 16%{?dist}
Summary: Library providing XML and HTML support
License: MIT
@ -56,33 +56,6 @@ Patch18: libxml2-2.9.7-CVE-2016-3709.patch
Patch19: libxml2-2.9.7-CVE-2022-40303.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2136568
Patch20: libxml2-2.9.7-CVE-2022-40304.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2186692
Patch21: libxml2-2.9.13-CVE-2023-28484.patch
Patch22: libxml2-2.9.13-CVE-2023-28484.2.patch
Patch23: libxml2-2.9.7-CVE-2023-29469.patch
# https://issues.redhat.com/browse/RHEL-5179
Patch24: libxml2-2.11.0-fix-CVE-2023-39615.patch
# https://issues.redhat.com/browse/RHEL-31056
Patch25: libxml2-2.9.7-CVE-2024-25062.patch
# https://issues.redhat.com/browse/RHEL-76289
Patch26: libxml2-2.9.13-CVE-2022-49043.patch
# https://issues.redhat.com/browse/RHEL-80122
Patch27: libxml2-2.9.13-CVE-2024-56171.patch
# https://issues.redhat.com/browse/RHEL-80137
Patch28: libxml2-2.9.13-CVE-2025-24928.patch
# https://issues.redhat.com/browse/RHEL-88198
Patch29: libxml2-2.9.13-CVE-2025-32414.patch
# https://issues.redhat.com/browse/RHEL-74345
Patch30: libxml2-clamp-output-bytes-overflow.patch
# https://issues.redhat.com/browse/RHEL-96498
Patch31: libxml2-2.9.13-CVE-2025-6021.patch
# https://issues.redhat.com/browse/RHEL-96398
# https://issues.redhat.com/browse/RHEL-96424
Patch32: libxml2-2.9.13-CVE-2025-49794.patch
# https://issues.redhat.com/browse/RHEL-102797
Patch33: libxml2-2.9.7-CVE-2025-7425.patch
# https://issues.redhat.com/browse/RHEL-100177
Patch34: libxml2-2.12.5-CVE-2025-32415.patch
BuildRequires: gcc
BuildRequires: cmake-rpm-macros
@ -254,40 +227,6 @@ gzip -9 -c doc/libxml2-api.xml > doc/libxml2-api.xml.gz
%{python3_sitearch}/libxml2mod.so
%changelog
* Tue Aug 05 2025 David King <dking@redhat.com> - 2.9.7.21.3
- Fix CVE-2025-32415 (RHEL-100177)
* Mon Jul 21 2025 David King <dking@redhat.com> - 2.9.7.21.2
- Fix CVE-2025-7425 (RHEL-102797)
* Mon Jun 16 2025 David King <dking@redhat.com> - 2.9.7-21.1
- Fix CVE-2025-6021 (RHEL-96498)
- Fix CVE-2025-49794 (RHEL-96398)
- Fix CVE-2025-49796 (RHEL-96424)
* Fri Jun 13 2025 David King <dking@redhat.com> - 2.9.7-21
- Fix integer overflow (RHEL-74345)
* Thu Jun 05 2025 David King <dking@redhat.com> - 2.9.7-20
- Fix CVE-2025-32414 (RHEL-88198)
* Tue Mar 11 2025 Michael Catanzaro <mcatanzaro@redhat.com> - 2.9.7-19
- Fix CVE-2024-56171 (RHEL-80122)
- Fix CVE-2025-24928 (RHEL-80137)
* Tue Feb 11 2025 David King <dking@redhat.com> - 2.9.7.18.2
- Fix CVE-2022-49043 (RHEL-76289)
* Mon Apr 29 2024 David King <amigadave@amigadave.com> - 2.9.7-18.1
- Fix CVE-2024-25062 (RHEL-31056)
* Thu Sep 14 2023 David King <amigadave@amigadave.com> - 2.9.7-18
- Fix CVE-2023-39615 (RHEL-5179)
* Fri Jul 14 2023 David King <amigadave@amigadave.com> - 2.9.7-17
- Fix CVE-2023-28484 (#2186692)
- Fix CVE-2023-29469 (#2186692)
* Wed Nov 02 2022 David King <dking@redhat.com> - 2.9.7-16
- Fix CVE-2022-40303 (#2136563)
- Fix CVE-2022-40304 (#2136568)