new file mode 100644
@@ -0,0 +1,802 @@
+From 87786d6200ae1f5ac98d21f04d451e17ff25a216 Mon Sep 17 00:00:00 2001
+From: David Kilzer <ddkilzer@apple.com>
+Reviewed-By: Aron Xu <aron@debian.org>
+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.
+Origin: https://launchpad.net/ubuntu/+source/libxml2/2.9.14+dfsg-1.3ubuntu3.6
+Ref : https://security-tracker.debian.org/tracker/CVE-2025-7425
+
+CVE: CVE-2025-7425
+Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/libxslt/-/issues/140]
+Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
+---
+ 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 ea6a4f2..9f439d6 100644
+--- a/HTMLparser.c
++++ b/HTMLparser.c
+@@ -2459,6 +2459,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 bb72e16..08786a3 100644
+--- a/SAX2.c
++++ b/SAX2.c
+@@ -899,7 +899,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,
+@@ -912,9 +912,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;
+ doc->standalone = ctxt->standalone;
+ } else {
+diff --git a/include/libxml/tree.h b/include/libxml/tree.h
+index a90a174..a013232 100644
+--- a/include/libxml/tree.h
++++ b/include/libxml/tree.h
+@@ -370,7 +370,6 @@ struct _xmlElement {
+ #endif
+ };
+
+-
+ /**
+ * XML_LOCAL_NAMESPACE:
+ *
+@@ -451,6 +450,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:
+ *
+@@ -512,6 +515,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:
+ *
+@@ -589,6 +597,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 6ab4bfe..19ae310 100644
+--- a/parser.c
++++ b/parser.c
+@@ -5663,7 +5663,7 @@ xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
+ xmlErrMemory(ctxt, "New Doc failed");
+ goto done;
+ }
+- 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,
+@@ -5734,7 +5734,7 @@ xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
+ xmlErrMemory(ctxt, "New Doc failed");
+ goto done;
+ }
+- ctxt->myDoc->properties = XML_DOC_INTERNAL;
++ XML_DOC_SET_PROPERTIES(ctxt->myDoc, XML_DOC_INTERNAL);
+ }
+
+ if (ctxt->myDoc->intSubset == NULL)
+@@ -7179,7 +7179,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);
+@@ -7580,7 +7580,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 b5c3fd8..75fcfd6 100644
+--- a/runxmlconf.c
++++ b/runxmlconf.c
+@@ -190,7 +190,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++;
+@@ -222,7 +222,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 f89e3cd..772ca62 100644
+--- a/tree.c
++++ b/tree.c
+@@ -1160,7 +1160,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
+@@ -2077,7 +2077,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);
+@@ -2794,7 +2794,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);
+ }
+
+@@ -6836,9 +6836,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);
+@@ -6858,7 +6858,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);
+ }
+@@ -9077,7 +9077,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.
+ */
+@@ -9093,11 +9093,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;
+@@ -9818,7 +9818,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 abefdc5..ae4bb82 100644
+--- a/valid.c
++++ b/valid.c
+@@ -1736,7 +1736,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,
+@@ -2109,7 +2109,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;
+@@ -2582,7 +2582,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);
+ }
+
+@@ -2661,7 +2661,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);
+@@ -2702,7 +2702,7 @@ xmlRemoveID(xmlDocPtr doc, xmlAttrPtr attr) {
+
+ xmlHashRemoveEntry(table, ID, xmlFreeIDTableEntry);
+ xmlFree(ID);
+- attr->atype = 0;
++ XML_ATTR_CLEAR_ATYPE(attr);
+ return(0);
+ }
+
+@@ -2987,8 +2987,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);
+@@ -3372,7 +3372,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
+@@ -3402,7 +3402,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
+@@ -3952,7 +3952,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);
+@@ -4014,7 +4014,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);
+@@ -4029,7 +4029,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)++;
+ }
+
+ /**
+@@ -4061,7 +4061,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,
+@@ -4072,7 +4072,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,
+@@ -4082,7 +4082,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 */
+@@ -4341,9 +4341,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",
+@@ -4362,19 +4362,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;
+
+@@ -4404,7 +4404,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;
+@@ -4429,7 +4429,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);
+ }
+@@ -4528,7 +4528,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,
+@@ -4578,7 +4578,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;
+
+@@ -4620,7 +4620,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;
+@@ -4658,10 +4658,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);
+@@ -6375,7 +6375,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,
+@@ -6383,7 +6383,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);
+@@ -6583,7 +6583,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 :
+@@ -6598,7 +6598,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;
+ }
+@@ -6606,14 +6606,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 5fdeb2b..5de168c 100644
+--- a/xmlreader.c
++++ b/xmlreader.c
+@@ -572,7 +572,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;
+@@ -631,7 +631,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;
+@@ -1017,7 +1017,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
+@@ -1265,7 +1265,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
+@@ -1279,7 +1279,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;
+@@ -1295,7 +1295,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);
+@@ -1308,7 +1308,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;
+ }
+@@ -1317,7 +1317,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) ||
+@@ -1341,7 +1341,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);
+ }
+@@ -1354,7 +1354,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);
+@@ -1536,7 +1536,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);
+@@ -2956,7 +2956,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);
+ }
+
+ /**
+@@ -3818,15 +3818,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 428e3c8..1f54acc 100644
+--- a/xmlschemas.c
++++ b/xmlschemas.c
+@@ -5895,7 +5895,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;
+
+@@ -5918,7 +5918,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 de95d94..76a7c87 100644
+--- a/xmlschemastypes.c
++++ b/xmlschemastypes.c
+@@ -2969,7 +2969,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;
+
+@@ -2982,7 +2982,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);
+ }
+ }
+ }
+@@ -3007,7 +3007,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:
+@@ -3021,7 +3021,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:{
+@@ -3052,7 +3052,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;
+ }
+@@ -3069,7 +3069,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.50.1
+
@@ -24,6 +24,7 @@ SRC_URI += "http://www.w3.org/XML/Test/xmlts20130923.tar;subdir=${BP};name=testt
file://CVE-2025-49794-CVE-2025-49796.patch \
file://CVE-2025-49795.patch \
file://CVE-2025-6170.patch \
+ file://CVE-2025-7425.patch \
"
SRC_URI[archive.sha256sum] = "c3d8c0c34aa39098f66576fe51969db12a5100b956233dc56506f7a8679be995"
CVE-2025-7425 libxslt: heap-use-after-free in xmlFreeID caused by `atype` corruption Origin: https://launchpad.net/ubuntu/+source/libxml2/2.9.14+dfsg-1.3ubuntu3.6 Ref : https://security-tracker.debian.org/tracker/CVE-2025-7425 Upstream-Status: Backport from https://gitlab.gnome.org/GNOME/libxslt/-/issues/140 Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com> --- .../libxml/libxml2/CVE-2025-7425.patch | 802 ++++++++++++++++++ meta/recipes-core/libxml/libxml2_2.12.10.bb | 1 + 2 files changed, 803 insertions(+) create mode 100644 meta/recipes-core/libxml/libxml2/CVE-2025-7425.patch