Description
Originally reported by @fereidani.
The following code:
<?php
$depth = 1_000_000;
$xml = str_repeat('<a>', $depth) . str_repeat('</a>', $depth);
$doc = Dom\XMLDocument::createFromString("<root>$xml</root>", LIBXML_PARSEHUGE);
$doc->saveXml();
Resulted in a stack overflow (SIGSEGV). The XML serializer recurses through dom_xml_serialize_element_node() -> dom_xml_serialization_algorithm() for
every element child, so a document nested deeply enough overflows the C stack.
Parsing untrusted input this deep normally requires LIBXML_PARSEHUGE, but it is also reachable without it by building the tree through Dom\HTMLDocument and importing it into a Dom\XMLDocument, so a fixed depth cap wouldn't cover it.
Adding a stack limit check in dom_xml_serialize_element_node(), as done in bd724bd (GH-15169) for var serialization, would be the appropriate fix.
A warning was added to the documentation: php/doc-en#5647
PHP Version
Operating System
No response
Description
Originally reported by @fereidani.
The following code:
Resulted in a stack overflow (SIGSEGV). The XML serializer recurses through
dom_xml_serialize_element_node()->dom_xml_serialization_algorithm()forevery element child, so a document nested deeply enough overflows the C stack.
Parsing untrusted input this deep normally requires LIBXML_PARSEHUGE, but it is also reachable without it by building the tree through
Dom\HTMLDocumentand importing it into aDom\XMLDocument, so a fixed depth cap wouldn't cover it.Adding a stack limit check in
dom_xml_serialize_element_node(), as done in bd724bd (GH-15169) for var serialization, would be the appropriate fix.A warning was added to the documentation: php/doc-en#5647
PHP Version
Operating System
No response