mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2024-12-25 23:21:26 +03:00
valid: Make xmlValidateElement non-recursive
Fixes call stack overflows when validating deeply nested documents. Found by OSS-Fuzz.
This commit is contained in:
parent
ca2bfecea9
commit
08f9d319eb
48
valid.c
48
valid.c
@ -6467,34 +6467,21 @@ name_ok:
|
||||
*/
|
||||
|
||||
int
|
||||
xmlValidateElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr elem) {
|
||||
xmlNodePtr child;
|
||||
xmlValidateElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr root) {
|
||||
xmlNodePtr elem;
|
||||
xmlAttrPtr attr;
|
||||
xmlNsPtr ns;
|
||||
const xmlChar *value;
|
||||
int ret = 1;
|
||||
|
||||
if (elem == NULL) return(0);
|
||||
|
||||
/*
|
||||
* XInclude elements were added after parsing in the infoset,
|
||||
* they don't really mean anything validation wise.
|
||||
*/
|
||||
if ((elem->type == XML_XINCLUDE_START) ||
|
||||
(elem->type == XML_XINCLUDE_END) ||
|
||||
(elem->type == XML_NAMESPACE_DECL))
|
||||
return(1);
|
||||
if (root == NULL) return(0);
|
||||
|
||||
CHECK_DTD;
|
||||
|
||||
/*
|
||||
* Entities references have to be handled separately
|
||||
*/
|
||||
if (elem->type == XML_ENTITY_REF_NODE) {
|
||||
return(1);
|
||||
}
|
||||
|
||||
elem = root;
|
||||
while (1) {
|
||||
ret &= xmlValidateOneElement(ctxt, doc, elem);
|
||||
|
||||
if (elem->type == XML_ELEMENT_NODE) {
|
||||
attr = elem->properties;
|
||||
while (attr != NULL) {
|
||||
@ -6504,6 +6491,7 @@ xmlValidateElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr elem) {
|
||||
xmlFree((char *)value);
|
||||
attr= attr->next;
|
||||
}
|
||||
|
||||
ns = elem->nsDef;
|
||||
while (ns != NULL) {
|
||||
if (elem->ns == NULL)
|
||||
@ -6511,16 +6499,28 @@ xmlValidateElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr elem) {
|
||||
ns, ns->href);
|
||||
else
|
||||
ret &= xmlValidateOneNamespace(ctxt, doc, elem,
|
||||
elem->ns->prefix, ns, ns->href);
|
||||
elem->ns->prefix, ns,
|
||||
ns->href);
|
||||
ns = ns->next;
|
||||
}
|
||||
|
||||
if (elem->children != NULL) {
|
||||
elem = elem->children;
|
||||
continue;
|
||||
}
|
||||
child = elem->children;
|
||||
while (child != NULL) {
|
||||
ret &= xmlValidateElement(ctxt, doc, child);
|
||||
child = child->next;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
if (elem == root)
|
||||
goto done;
|
||||
if (elem->next != NULL)
|
||||
break;
|
||||
elem = elem->parent;
|
||||
}
|
||||
elem = elem->next;
|
||||
}
|
||||
|
||||
done:
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user