mirror of
https://github.com/php/php-src.git
synced 2025-08-15 13:38:49 +02:00
Merge branch 'PHP-8.4'
* PHP-8.4: Fix GH-17040: SimpleXML's unset can break DOM objects
This commit is contained in:
commit
fc48fd8653
2 changed files with 40 additions and 11 deletions
|
@ -53,7 +53,17 @@ static void php_sxe_iterator_move_forward(zend_object_iterator *iter);
|
|||
static void php_sxe_iterator_rewind(zend_object_iterator *iter);
|
||||
static zend_result sxe_object_cast_ex(zend_object *readobj, zval *writeobj, int type);
|
||||
|
||||
/* {{{ node_as_zval() */
|
||||
static void sxe_unlink_node(xmlNodePtr node)
|
||||
{
|
||||
xmlUnlinkNode(node);
|
||||
/* Only destroy the nodes if we have no objects using them anymore.
|
||||
* Don't assume simplexml owns these. */
|
||||
if (!node->_private) {
|
||||
php_libxml_node_free_resource(node);
|
||||
}
|
||||
}
|
||||
|
||||
/* {{{ _node_as_zval() */
|
||||
static void node_as_zval(php_sxe_object *sxe, xmlNodePtr node, zval *value, SXE_ITER itertype, zend_string *name, zend_string *nsprefix, int isprefix)
|
||||
{
|
||||
php_sxe_object *subnode;
|
||||
|
@ -558,8 +568,7 @@ next_iter:
|
|||
}
|
||||
if (value_str) {
|
||||
while ((tempnode = (xmlNodePtr) newnode->children)) {
|
||||
xmlUnlinkNode(tempnode);
|
||||
php_libxml_node_free_resource((xmlNodePtr) tempnode);
|
||||
sxe_unlink_node(tempnode);
|
||||
}
|
||||
change_node_zval(newnode, value_str);
|
||||
}
|
||||
|
@ -832,8 +841,7 @@ static void sxe_prop_dim_delete(zend_object *object, zval *member, bool elements
|
|||
while (attr && nodendx <= Z_LVAL_P(member)) {
|
||||
if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && match_ns((xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) {
|
||||
if (nodendx == Z_LVAL_P(member)) {
|
||||
xmlUnlinkNode((xmlNodePtr) attr);
|
||||
php_libxml_node_free_resource((xmlNodePtr) attr);
|
||||
sxe_unlink_node((xmlNodePtr) attr);
|
||||
break;
|
||||
}
|
||||
nodendx++;
|
||||
|
@ -844,8 +852,7 @@ static void sxe_prop_dim_delete(zend_object *object, zval *member, bool elements
|
|||
while (attr) {
|
||||
anext = attr->next;
|
||||
if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && xmlStrEqual(attr->name, (xmlChar *)Z_STRVAL_P(member)) && match_ns((xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) {
|
||||
xmlUnlinkNode((xmlNodePtr) attr);
|
||||
php_libxml_node_free_resource((xmlNodePtr) attr);
|
||||
sxe_unlink_node((xmlNodePtr) attr);
|
||||
break;
|
||||
}
|
||||
attr = anext;
|
||||
|
@ -860,8 +867,7 @@ static void sxe_prop_dim_delete(zend_object *object, zval *member, bool elements
|
|||
}
|
||||
node = sxe_get_element_by_offset(sxe, Z_LVAL_P(member), node, NULL);
|
||||
if (node) {
|
||||
xmlUnlinkNode(node);
|
||||
php_libxml_node_free_resource(node);
|
||||
sxe_unlink_node(node);
|
||||
}
|
||||
} else {
|
||||
node = node->children;
|
||||
|
@ -871,8 +877,7 @@ static void sxe_prop_dim_delete(zend_object *object, zval *member, bool elements
|
|||
SKIP_TEXT(node);
|
||||
|
||||
if (xmlStrEqual(node->name, (xmlChar *)Z_STRVAL_P(member)) && match_ns(node, sxe->iter.nsprefix, sxe->iter.isprefix)) {
|
||||
xmlUnlinkNode(node);
|
||||
php_libxml_node_free_resource(node);
|
||||
sxe_unlink_node(node);
|
||||
}
|
||||
|
||||
next_iter:
|
||||
|
|
24
ext/simplexml/tests/gh17040.phpt
Normal file
24
ext/simplexml/tests/gh17040.phpt
Normal file
|
@ -0,0 +1,24 @@
|
|||
--TEST--
|
||||
GH-17040 (SimpleXML's unset can break DOM objects)
|
||||
--EXTENSIONS--
|
||||
dom
|
||||
simplexml
|
||||
--FILE--
|
||||
<?php
|
||||
$dom = new DOMDocument;
|
||||
$tag = $dom->appendChild($dom->createElement("style"));
|
||||
$html = simplexml_import_dom($tag);
|
||||
unset($html[0]);
|
||||
$tag->append("foo");
|
||||
echo $dom->saveXML(), "\n";
|
||||
echo $dom->saveXML($tag), "\n";
|
||||
var_dump($html);
|
||||
?>
|
||||
--EXPECT--
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<style>foo</style>
|
||||
object(SimpleXMLElement)#3 (1) {
|
||||
[0]=>
|
||||
string(3) "foo"
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue