diff --git a/SOURCES/RHEL-119283.patch b/SOURCES/RHEL-119283.patch new file mode 100644 index 0000000..4d5ec32 --- /dev/null +++ b/SOURCES/RHEL-119283.patch @@ -0,0 +1,112 @@ +From 677a42645ef22b5a50741bad5facf9d8a8bc6d21 Mon Sep 17 00:00:00 2001 +From: Nick Wellnhofer +Date: Thu, 28 Jul 2022 20:21:24 +0200 +Subject: [PATCH] Make XPath depth check work with recursive invocations + +EXSLT functions like dyn:map or dyn:evaluate invoke xmlXPathRunEval +recursively. Don't set depth to zero but keep and restore the original +value to avoid stack overflows when abusing these functions. +--- + xpath.c | 23 +++++++++++++++++------ + 1 file changed, 17 insertions(+), 6 deletions(-) + +diff --git a/xpath.c b/xpath.c +index f59ef41d4..4a6f0e216 100644 +--- a/xpath.c ++++ b/xpath.c +@@ -13884,12 +13884,11 @@ static int + xmlXPathRunEval(xmlXPathParserContextPtr ctxt, int toBool) + { + xmlXPathCompExprPtr comp; ++ int oldDepth; + + if ((ctxt == NULL) || (ctxt->comp == NULL)) + return(-1); + +- ctxt->context->depth = 0; +- + if (ctxt->valueTab == NULL) { + /* Allocate the value stack */ + ctxt->valueTab = (xmlXPathObjectPtr *) +@@ -13943,11 +13942,13 @@ xmlXPathRunEval(xmlXPathParserContextPtr ctxt, int toBool) + "xmlXPathRunEval: last is less than zero\n"); + return(-1); + } ++ oldDepth = ctxt->context->depth; + if (toBool) + return(xmlXPathCompOpEvalToBoolean(ctxt, + &comp->steps[comp->last], 0)); + else + xmlXPathCompOpEval(ctxt, &comp->steps[comp->last]); ++ ctxt->context->depth = oldDepth; + + return(0); + } +@@ -14218,6 +14219,7 @@ xmlXPathCompExprPtr + xmlXPathCtxtCompile(xmlXPathContextPtr ctxt, const xmlChar *str) { + xmlXPathParserContextPtr pctxt; + xmlXPathCompExprPtr comp; ++ int oldDepth = 0; + + #ifdef XPATH_STREAMING + comp = xmlXPathTryStreamCompile(ctxt, str); +@@ -14231,8 +14233,10 @@ xmlXPathCtxtCompile(xmlXPathContextPtr ctxt, const xmlChar *str) { + if (pctxt == NULL) + return NULL; + if (ctxt != NULL) +- ctxt->depth = 0; ++ oldDepth = ctxt->depth; + xmlXPathCompileExpr(pctxt, 1); ++ if (ctxt != NULL) ++ ctxt->depth = oldDepth; + + if( pctxt->error != XPATH_EXPRESSION_OK ) + { +@@ -14253,8 +14257,10 @@ xmlXPathCtxtCompile(xmlXPathContextPtr ctxt, const xmlChar *str) { + comp = pctxt->comp; + if ((comp->nbStep > 1) && (comp->last >= 0)) { + if (ctxt != NULL) +- ctxt->depth = 0; ++ oldDepth = ctxt->depth; + xmlXPathOptimizeExpression(pctxt, &comp->steps[comp->last]); ++ if (ctxt != NULL) ++ ctxt->depth = oldDepth; + } + pctxt->comp = NULL; + } +@@ -14410,6 +14416,7 @@ xmlXPathEvalExpr(xmlXPathParserContextPtr ctxt) { + #ifdef XPATH_STREAMING + xmlXPathCompExprPtr comp; + #endif ++ int oldDepth = 0; + + if (ctxt == NULL) return; + +@@ -14423,8 +14430,10 @@ xmlXPathEvalExpr(xmlXPathParserContextPtr ctxt) { + #endif + { + if (ctxt->context != NULL) +- ctxt->context->depth = 0; ++ oldDepth = ctxt->context->depth; + xmlXPathCompileExpr(ctxt, 1); ++ if (ctxt->context != NULL) ++ ctxt->context->depth = oldDepth; + CHECK_ERROR; + + /* Check for trailing characters. */ +@@ -14433,9 +14442,11 @@ xmlXPathEvalExpr(xmlXPathParserContextPtr ctxt) { + + if ((ctxt->comp->nbStep > 1) && (ctxt->comp->last >= 0)) { + if (ctxt->context != NULL) +- ctxt->context->depth = 0; ++ oldDepth = ctxt->context->depth; + xmlXPathOptimizeExpression(ctxt, + &ctxt->comp->steps[ctxt->comp->last]); ++ if (ctxt->context != NULL) ++ ctxt->context->depth = oldDepth; + } + } + +-- +GitLab + diff --git a/SOURCES/libxml2-2.12.5-CVE-2025-32415.patch b/SOURCES/libxml2-2.12.5-CVE-2025-32415.patch new file mode 100644 index 0000000..295dbb4 --- /dev/null +++ b/SOURCES/libxml2-2.12.5-CVE-2025-32415.patch @@ -0,0 +1,38 @@ +From 384cc7c182fc00c6d5e2ab4b5e3671b2e3f93c84 Mon Sep 17 00:00:00 2001 +From: Nick Wellnhofer +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 + diff --git a/SOURCES/libxml2-2.12.5-CVE-2025-6170.patch b/SOURCES/libxml2-2.12.5-CVE-2025-6170.patch new file mode 100644 index 0000000..b982392 --- /dev/null +++ b/SOURCES/libxml2-2.12.5-CVE-2025-6170.patch @@ -0,0 +1,98 @@ +From 79abeb402f5570330f092b3dbe326798079231c9 Mon Sep 17 00:00:00 2001 +From: David King +Date: Tue, 16 Jun 2026 14:59:25 +0100 +Subject: [PATCH] Fix potential buffer overflows of interactive shell + +CVE-2025-6170 + +Fixes #941 on 2.12 branch. Based on upstream commit +069bcda17d8194e9582c64dd4bc9dac99b015810 by Michael Mann. +--- + debugXML.c | 15 ++++++++++----- + xmllint.c | 8 +++++--- + 2 files changed, 15 insertions(+), 8 deletions(-) + +diff --git a/debugXML.c b/debugXML.c +index 303515ec..63b77ba6 100644 +--- a/debugXML.c ++++ b/debugXML.c +@@ -2779,6 +2779,10 @@ xmlShellPwd(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED, char *buffer, + return (0); + } + ++#define MAX_PROMPT_SIZE 500 ++#define MAX_ARG_SIZE 400 ++#define MAX_COMMAND_SIZE 100 ++ + /** + * xmlShell: + * @doc: the initial document +@@ -2794,10 +2798,10 @@ void + xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input, + FILE * output) + { +- char prompt[500] = "/ > "; ++ char prompt[MAX_PROMPT_SIZE] = "/ > "; + char *cmdline = NULL, *cur; +- char command[100]; +- char arg[400]; ++ char command[MAX_COMMAND_SIZE]; ++ char arg[MAX_ARG_SIZE]; + int i; + xmlShellCtxtPtr ctxt; + xmlXPathObjectPtr list; +@@ -2855,7 +2859,8 @@ xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input, + cur++; + i = 0; + while ((*cur != ' ') && (*cur != '\t') && +- (*cur != '\n') && (*cur != '\r')) { ++ (*cur != '\n') && (*cur != '\r') && ++ (i < (MAX_COMMAND_SIZE - 1))) { + if (*cur == 0) + break; + command[i++] = *cur++; +@@ -2870,7 +2875,7 @@ xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input, + while ((*cur == ' ') || (*cur == '\t')) + cur++; + i = 0; +- while ((*cur != '\n') && (*cur != '\r') && (*cur != 0)) { ++ while ((*cur != '\n') && (*cur != '\r') && (*cur != 0) && (i < (MAX_ARG_SIZE-1))) { + if (*cur == 0) + break; + arg[i++] = *cur++; +diff --git a/xmllint.c b/xmllint.c +index 4d84c640..4b2c06d9 100644 +--- a/xmllint.c ++++ b/xmllint.c +@@ -722,6 +722,8 @@ xmlHTMLValidityWarning(void *ctx, const char *msg, ...) + xmlHTMLEncodeSend(); + } + ++#define MAX_PROMPT_SIZE 500 ++ + /************************************************************************ + * * + * Shell Interface * +@@ -752,16 +754,16 @@ xmlShellReadline(char *prompt) { + + return (line_read); + #else +- char line_read[501]; ++ char line_read[MAX_PROMPT_SIZE+1]; + char *ret; + int len; + + if (prompt != NULL) + fprintf(stdout, "%s", prompt); + fflush(stdout); +- if (!fgets(line_read, 500, stdin)) ++ if (!fgets(line_read, MAX_PROMPT_SIZE, stdin)) + return(NULL); +- line_read[500] = 0; ++ line_read[MAX_PROMPT_SIZE] = 0; + len = strlen(line_read); + ret = (char *) malloc(len + 1); + if (ret != NULL) { +-- +2.54.0 + diff --git a/SOURCES/libxml2-2.9.13-CVE-2024-34459.patch b/SOURCES/libxml2-2.9.13-CVE-2024-34459.patch new file mode 100644 index 0000000..456bee1 --- /dev/null +++ b/SOURCES/libxml2-2.9.13-CVE-2024-34459.patch @@ -0,0 +1,26 @@ +From 8ddc7f13337c9fe7c6b6e616f404b0fffb8a5145 Mon Sep 17 00:00:00 2001 +From: Nick Wellnhofer +Date: Wed, 8 May 2024 11:49:31 +0200 +Subject: [PATCH] [CVE-2024-34459] Fix buffer overread with `xmllint --htmlout` + +Add a missing bounds check. +--- + xmllint.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/xmllint.c b/xmllint.c +index 0e433b721..62f6b0273 100644 +--- a/xmllint.c ++++ b/xmllint.c +@@ -559,7 +559,7 @@ xmlHTMLPrintFileContext(xmlParserInputPtr input) { + len = strlen(buffer); + snprintf(&buffer[len], sizeof(buffer) - len, "\n"); + cur = input->cur; +- while ((*cur == '\n') || (*cur == '\r')) ++ while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) + cur--; + n = 0; + while ((cur != base) && (n++ < 80)) { +-- +GitLab + diff --git a/SOURCES/libxml2-2.9.13-CVE-2025-32414.patch b/SOURCES/libxml2-2.9.13-CVE-2025-32414.patch new file mode 100644 index 0000000..c163feb --- /dev/null +++ b/SOURCES/libxml2-2.9.13-CVE-2025-32414.patch @@ -0,0 +1,60 @@ +diff --git a/python/libxml.c b/python/libxml.c +index 5dea5026..478af305 100644 +--- a/python/libxml.c ++++ b/python/libxml.c +@@ -237,7 +237,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); +@@ -272,10 +274,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); + } +@@ -299,7 +303,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); +@@ -334,10 +340,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); + } diff --git a/SOURCES/libxml2-2.9.13-CVE-2025-49794.patch b/SOURCES/libxml2-2.9.13-CVE-2025-49794.patch new file mode 100644 index 0000000..e2e7014 --- /dev/null +++ b/SOURCES/libxml2-2.9.13-CVE-2025-49794.patch @@ -0,0 +1,194 @@ +From b2a28a861e9d43a23b877c3994daa28f8af69618 Mon Sep 17 00:00:00 2001 +From: Nick Wellnhofer +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 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ +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 @@ ++ ++ ++ +-- +2.49.0 + diff --git a/SOURCES/libxml2-2.9.13-CVE-2025-6021.patch b/SOURCES/libxml2-2.9.13-CVE-2025-6021.patch new file mode 100644 index 0000000..faced86 --- /dev/null +++ b/SOURCES/libxml2-2.9.13-CVE-2025-6021.patch @@ -0,0 +1,49 @@ +From 1256dce1c2c928e1436a7e8bd8b40113099383c8 Mon Sep 17 00:00:00 2001 +From: Nick Wellnhofer +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 /* for memset() only ! */ + #include ++#include + #include + #ifdef HAVE_CTYPE_H + #include +@@ -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 + diff --git a/SOURCES/libxml2-2.9.13-CVE-2025-7425.patch b/SOURCES/libxml2-2.9.13-CVE-2025-7425.patch new file mode 100644 index 0000000..9f3a260 --- /dev/null +++ b/SOURCES/libxml2-2.9.13-CVE-2025-7425.patch @@ -0,0 +1,795 @@ +From d82c3d74f2b1d580da20a39f23faef7a56cd8176 Mon Sep 17 00:00:00 2001 +From: David Kilzer +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 e720bb20..1307f71f 100644 +--- a/HTMLparser.c ++++ b/HTMLparser.c +@@ -2514,6 +2514,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 03192465..18c747d1 100644 +--- a/SAX2.c ++++ b/SAX2.c +@@ -970,7 +970,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, +@@ -983,9 +983,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 1e79be92..61178b2c 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 information */ + }; + ++#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 1bc37137..0eb4ec4b 100644 +--- a/parser.c ++++ b/parser.c +@@ -5516,7 +5516,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, +@@ -5587,7 +5587,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) +@@ -7028,7 +7028,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); +@@ -7412,7 +7412,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 8a37aa8f..601a0af4 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 3b0d0397..72ec7cae 100644 +--- a/tree.c ++++ b/tree.c +@@ -1189,7 +1189,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 +@@ -2116,7 +2116,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); +@@ -2835,7 +2835,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); + } + +@@ -6946,9 +6946,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); +@@ -6968,7 +6968,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); + } +@@ -9245,7 +9245,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. + */ +@@ -9261,11 +9261,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; +@@ -9985,7 +9985,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 ed3c8503..d6acd132 100644 +--- a/valid.c ++++ b/valid.c +@@ -1906,7 +1906,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, +@@ -2279,7 +2279,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; +@@ -2758,7 +2758,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); + } + +@@ -2837,7 +2837,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); +@@ -2878,7 +2878,7 @@ xmlRemoveID(xmlDocPtr doc, xmlAttrPtr attr) { + + xmlHashRemoveEntry(table, ID, xmlFreeIDTableEntry); + xmlFree(ID); +- attr->atype = 0; ++ XML_ATTR_CLEAR_ATYPE(attr); + return(0); + } + +@@ -3157,8 +3157,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); +@@ -3532,7 +3532,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 +@@ -3562,7 +3562,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 +@@ -4112,7 +4112,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); +@@ -4174,7 +4174,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); +@@ -4189,7 +4189,7 @@ xmlValidateAttributeIdCallback(void *payload, void *data, + const xmlChar *name ATTRIBUTE_UNUSED) { + xmlAttributePtr attr = (xmlAttributePtr) payload; + int *count = (int *) data; +- if (attr->atype == XML_ATTRIBUTE_ID) (*count)++; ++ if (XML_ATTR_GET_ATYPE(attr) == XML_ATTRIBUTE_ID) (*count)++; + } + + /** +@@ -4221,7 +4221,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, +@@ -4232,7 +4232,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, +@@ -4242,7 +4242,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 */ +@@ -4501,9 +4501,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", +@@ -4522,19 +4522,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; + +@@ -4564,7 +4564,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; +@@ -4589,7 +4589,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); + } +@@ -4688,7 +4688,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, +@@ -4738,7 +4738,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; + +@@ -4780,7 +4780,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; +@@ -4818,10 +4818,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); +@@ -6573,7 +6573,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, +@@ -6581,7 +6581,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); +@@ -6781,7 +6781,7 @@ xmlValidateAttributeCallback(void *payload, void *data, + + 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 : +@@ -6796,7 +6796,7 @@ xmlValidateAttributeCallback(void *payload, void *data, + 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; + } +@@ -6804,14 +6804,14 @@ xmlValidateAttributeCallback(void *payload, void *data, + 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 72e40b03..e5cc7d27 100644 +--- a/xmlreader.c ++++ b/xmlreader.c +@@ -753,7 +753,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; +@@ -818,7 +818,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; +@@ -1216,7 +1216,7 @@ skip_children: + 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 +@@ -1467,7 +1467,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 +@@ -1481,7 +1481,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; +@@ -1497,7 +1497,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) { + if (oldnode == tmp) + oldnode = NULL; + xmlUnlinkNode(tmp); +@@ -1510,7 +1510,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; + } +@@ -1519,7 +1519,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) || +@@ -1546,7 +1546,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); + } +@@ -1559,7 +1559,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); +@@ -1740,7 +1740,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); +@@ -3166,7 +3166,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); + } + + /** +@@ -4034,15 +4034,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 64fe146a..3d1f790c 100644 +--- a/xmlschemas.c ++++ b/xmlschemas.c +@@ -6024,7 +6024,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; + +@@ -6047,7 +6047,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 af31be5f..d40da494 100644 +--- a/xmlschemastypes.c ++++ b/xmlschemastypes.c +@@ -2867,7 +2867,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; + +@@ -2880,7 +2880,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); + } + } + } +@@ -2905,7 +2905,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: +@@ -2919,7 +2919,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:{ +@@ -2950,7 +2950,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; + } +@@ -2967,7 +2967,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 + diff --git a/SPECS/libxml2.spec b/SPECS/libxml2.spec index ead81e5..43d1204 100644 --- a/SPECS/libxml2.spec +++ b/SPECS/libxml2.spec @@ -1,6 +1,6 @@ Name: libxml2 Version: 2.9.13 -Release: 9%{?dist} +Release: 16%{?dist} Summary: Library providing XML and HTML support License: MIT @@ -30,6 +30,24 @@ Patch10: libxml2-2.9.13-CVE-2022-49043.patch Patch11: libxml2-2.9.13-CVE-2024-56171.patch # https://issues.redhat.com/browse/RHEL-80142 Patch12: libxml2-2.9.13-CVE-2025-24928.patch +# https://issues.redhat.com/browse/RHEL-96507 +Patch13: libxml2-2.9.13-CVE-2025-6021.patch +# https://issues.redhat.com/browse/RHEL-96405 +# https://issues.redhat.com/browse/RHEL-96431 +Patch14: libxml2-2.9.13-CVE-2025-49794.patch +# https://issues.redhat.com/browse/RHEL-102806 +Patch15: libxml2-2.9.13-CVE-2025-7425.patch +# https://issues.redhat.com/browse/RHEL-100182 +Patch16: libxml2-2.12.5-CVE-2025-32415.patch +# https://issues.redhat.com/browse/RHEL-99873 +Patch17: libxml2-2.9.13-CVE-2025-32414.patch +# https://issues.redhat.com/browse/RHEL-119283 +Patch18: RHEL-119283.patch +# https://redhat.atlassian.net/browse/RHEL-36406 +Patch19: libxml2-2.9.13-CVE-2024-34459.patch +# https://gitlab.gnome.org/GNOME/libxml2/-/merge_requests/321 +# https://redhat.atlassian.net/browse/RHEL-186744 +Patch20: libxml2-2.12.5-CVE-2025-6170.patch BuildRequires: cmake-rpm-macros BuildRequires: gcc @@ -158,6 +176,30 @@ gzip -9 -c doc/libxml2-api.xml > doc/libxml2-api.xml.gz %{python3_sitearch}/libxml2mod.so %changelog +* Tue Jun 16 2026 David King - 2.9.13-16 +- Fix CVE-2025-6170 (RHEL-186744) + +* Mon May 18 2026 David King - 2.9.13-15 +- Fix CVE-2024-34459 (RHEL-36406) + +* Tue Nov 13 2025 Laura Barcziova - 2.9.13-14 +- Rebuilt for the correct target in RHEL (9.7-z) (RHEL-119283) + +* Tue Nov 04 2025 RHEL Packaging Agent - 2.9.13-13 +- Fix CVE-2025-9714 (RHEL-119283) + +* Tue Aug 05 2025 David King - 2.9.13-12 +- Fix CVE-2025-32415 (RHEL-100182) +- Fix CVE-2025-32414 (RHEL-99873) + +* Mon Jul 21 2025 David King - 2.9.13-11 +- Fix CVE-2025-7425 (RHEL-102806) + +* Mon Jun 16 2025 David King - 2.9.13-10 +- Fix CVE-2025-6021 (RHEL-96507) +- Fix CVE-2025-49794 (RHEL-96405) +- Fix CVE-2025-49796 (RHEL-96431) + * Wed Feb 26 2025 David King - 2.9.13-9 - Fix CVE-2025-24928 (RHEL-80142)