mirror of
https://github.com/php/php-src.git
synced 2025-08-15 13:38:49 +02:00
Merge branch 'PHP-8.3'
* PHP-8.3: Fix GH-14702: DOMDocument::xinclude() crash
This commit is contained in:
commit
bcdba83cbb
2 changed files with 88 additions and 1 deletions
|
@ -1706,9 +1706,41 @@ static void php_dom_remove_xinclude_nodes(xmlNodePtr cur) /* {{{ */
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ Substitutes xincludes in a DomDocument */
|
static void dom_xinclude_strip_references(xmlNodePtr basep)
|
||||||
|
{
|
||||||
|
php_libxml_node_free_resource(basep);
|
||||||
|
|
||||||
|
xmlNodePtr current = basep->children;
|
||||||
|
|
||||||
|
while (current) {
|
||||||
|
php_libxml_node_free_resource(current);
|
||||||
|
current = php_dom_next_in_tree_order(current, basep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* See GH-14702.
|
||||||
|
* We have to remove userland references to xinclude fallback nodes because libxml2 will make clones of these
|
||||||
|
* and remove the original nodes. If the originals are removed while there are still userland references
|
||||||
|
* this will cause memory corruption. */
|
||||||
|
static void dom_xinclude_strip_fallback_references(const xmlNode *basep)
|
||||||
|
{
|
||||||
|
xmlNodePtr current = basep->children;
|
||||||
|
|
||||||
|
while (current) {
|
||||||
|
if (current->type == XML_ELEMENT_NODE && current->ns != NULL && current->_private != NULL
|
||||||
|
&& xmlStrEqual(current->name, XINCLUDE_FALLBACK)
|
||||||
|
&& (xmlStrEqual(current->ns->href, XINCLUDE_NS) || xmlStrEqual(current->ns->href, XINCLUDE_OLD_NS))) {
|
||||||
|
dom_xinclude_strip_references(current);
|
||||||
|
}
|
||||||
|
|
||||||
|
current = php_dom_next_in_tree_order(current, basep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int dom_perform_xinclude(xmlDocPtr docp, dom_object *intern, zend_long flags)
|
static int dom_perform_xinclude(xmlDocPtr docp, dom_object *intern, zend_long flags)
|
||||||
{
|
{
|
||||||
|
dom_xinclude_strip_fallback_references((const xmlNode *) docp);
|
||||||
|
|
||||||
PHP_LIBXML_SANITIZE_GLOBALS(xinclude);
|
PHP_LIBXML_SANITIZE_GLOBALS(xinclude);
|
||||||
int err = xmlXIncludeProcessFlags(docp, (int)flags);
|
int err = xmlXIncludeProcessFlags(docp, (int)flags);
|
||||||
PHP_LIBXML_RESTORE_GLOBALS(xinclude);
|
PHP_LIBXML_RESTORE_GLOBALS(xinclude);
|
||||||
|
@ -1730,6 +1762,7 @@ static int dom_perform_xinclude(xmlDocPtr docp, dom_object *intern, zend_long fl
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* {{{ Substitutues xincludes in a DomDocument */
|
||||||
PHP_METHOD(DOMDocument, xinclude)
|
PHP_METHOD(DOMDocument, xinclude)
|
||||||
{
|
{
|
||||||
xmlDoc *docp;
|
xmlDoc *docp;
|
||||||
|
|
54
ext/dom/tests/gh14702.phpt
Normal file
54
ext/dom/tests/gh14702.phpt
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
--TEST--
|
||||||
|
GH-14702 (DOMDocument::xinclude() crash)
|
||||||
|
--EXTENSIONS--
|
||||||
|
dom
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
$doc = new DOMDocument();
|
||||||
|
$doc->loadXML(<<<XML
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<root>
|
||||||
|
<child/>
|
||||||
|
<include href="foo" xmlns="http://www.w3.org/2001/XInclude">
|
||||||
|
<fallback/>
|
||||||
|
</include>
|
||||||
|
<keep/>
|
||||||
|
</root>
|
||||||
|
XML);
|
||||||
|
$xi = $doc->createElementNS('http://www.w3.org/2001/XInclude', 'xi:include');
|
||||||
|
$xi->setAttribute('href', 'nonexistent');
|
||||||
|
|
||||||
|
$fallback = $doc->createElementNS('http://www.w3.org/2001/XInclude', 'xi:fallback');
|
||||||
|
$xi->appendChild($fallback);
|
||||||
|
$child1 = $fallback->appendChild($doc->createElement('fallback-child1'));
|
||||||
|
$child2 = $fallback->appendChild($doc->createElement('fallback-child2'));
|
||||||
|
|
||||||
|
$xpath = new DOMXPath($doc);
|
||||||
|
$toReplace = $xpath->query('//child')->item(0);
|
||||||
|
$toReplace->parentNode->replaceChild($xi, $toReplace);
|
||||||
|
|
||||||
|
$keep = $doc->documentElement->lastElementChild;
|
||||||
|
|
||||||
|
var_dump(@$doc->xinclude());
|
||||||
|
echo $doc->saveXML();
|
||||||
|
|
||||||
|
var_dump($keep->nodeName);
|
||||||
|
|
||||||
|
$keep->textContent = 'still works';
|
||||||
|
echo $doc->saveXML();
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
int(2)
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<root>
|
||||||
|
<fallback-child1/><fallback-child2/>
|
||||||
|
|
||||||
|
<keep/>
|
||||||
|
</root>
|
||||||
|
string(4) "keep"
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<root>
|
||||||
|
<fallback-child1/><fallback-child2/>
|
||||||
|
|
||||||
|
<keep>still works</keep>
|
||||||
|
</root>
|
Loading…
Add table
Add a link
Reference in a new issue