#36756 [Asn->Csd]: DOMDocument::removeChild corrupts node
| From: | rrichards@php.net | Date: | Sat, 18 Mar 2006 11:48:14 +0000 |
| Subject: | #36756 [Asn->Csd]: DOMDocument::removeChild corrupts node | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-94496@lists.php.net to get a copy of this message | ||
ID: 36756
Updated by: rrichards@php.net
Reported By: olaf at 7val dot com
-Status: Assigned
+Status: Closed
Bug Type: DOM XML related
Operating System: Linux
PHP Version: 5.1.2
Assigned To: rrichards
New Comment:
This bug has been fixed in CVS.
Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
Thank you for the report, and for helping us make PHP better.
Warning has been added when node no longer exists and property is
accessed.
Previous Comments:
------------------------------------------------------------------------
[2006-03-16 12:24:35] rrichards@php.net
Assigning to self. Node is not corrupted. It just doesn't exist. Try
calling $node->hasChildNodes() and you will see the warning. I'll look
at adding a warning when accessing properties in this case.
Behavior will not change. When subtree is unlinked and root of subtree
is not referenced entire subtree is released to avoid memory issues.
Changing this would slow down all tree based extensions (dom, simplexml
and xsl) drastically, so always reference the detached tree's root if
you want to use it again.
------------------------------------------------------------------------
[2006-03-16 11:39:06] olaf at 7val dot com
I double checked documentation, node corruption is not mentioned
there.
if the return value of removeChild is assigned to a variable,
everything works as expected:
-----------------8<---------------
$dom = DOMDocument::loadXML('<root><child/></root>');
$xpath = new DOMXpath($dom);
$node = $xpath->query('//child')->item(0);
echo $node->nodeName . "\n";
$res = $GLOBALS['dom']->removeChild($GLOBALS['dom']->firstChild);
echo "nodeType: " . $node->nodeType . "\n";
echo "nodeName: " .$node->nodeName . "\n";
echo "parentNode: " .$node->parentNode . "\n";
---------------->8--------------------
if the return value is ignored:
----------------------------8<---------------
$dom = DOMDocument::loadXML('<root><child/></root>');
$xpath = new DOMXpath($dom);
$node = $xpath->query('//child')->item(0);
echo $node->nodeName . "\n";
$GLOBALS['dom']->removeChild($GLOBALS['dom']->firstChild);
echo "nodeType: " . $node->nodeType . "\n";
echo "nodeName: " .$node->nodeName . "\n";
echo "parentNode: " .$node->parentNode . "\n";
-------------------------->8------------
or goes out of scope:
--------------------8<-----------
$dom = DOMDocument::loadXML('<root><child/></root>');
$xpath = new DOMXpath($dom);
$node = $xpath->query('/root/child')->item(0);
echo $node->nodeName;
function test()
{
$x = $GLOBALS['dom']->removeChild($GLOBALS['dom']->firstChild);
}
test();
echo $node->nodeName;
-------------------->8-----------
$node gets corrupted.
------------------------------------------------------------------------
[2006-03-16 11:20:57] tony2001@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to
report
a bug at http://bugs.php.net/how-to-report.php
------------------------------------------------------------------------
[2006-03-16 09:47:53] olaf at 7val dot com
Description:
------------
Using DOMDocument::removeChild corrupts node in the document in some
cases.
Given a node $node and removing a parent node of this node renders
$node unusable (properties are gone, but $node is still of class
DOMElement).
Reproduce code:
---------------
<?php
// This works as expected
$dom = DOMDocument::loadXML('<root><child/></root>');
$xpath = new DOMXpath($dom);
$node = $xpath->query('/root')->item(0);
echo $node->nodeName . "\n";
$dom->removeChild($GLOBALS['dom']->firstChild);
echo "nodeType: " . $node->nodeType . "\n";
echo "nodeName: " .$node->nodeName . "\n";
echo "parentNode: " .$node->parentNode . "\n";
// This breaks "$node"
$dom = DOMDocument::loadXML('<root><child/></root>');
$xpath = new DOMXpath($dom);
$node = $xpath->query('//child')->item(0);
echo $node->nodeName . "\n";
$GLOBALS['dom']->removeChild($GLOBALS['dom']->firstChild);
echo "nodeType: " . $node->nodeType . "\n";
echo "nodeName: " .$node->nodeName . "\n";
echo "parentNode: " .$node->parentNode . "\n";
echo "\n";
?>
Expected result:
----------------
Properties of $node should still exists, see part1:
root
nodeType: 1
nodeName: root
parentNode:
Actual result:
--------------
Properties are gone
child
Notice: Undefined property: DOMElement::$nodeType in
/home/olaf/test/test.php on line 20
nodeType:
Notice: Undefined property: DOMElement::$nodeName in
/home/olaf/test/test.php on line 21
nodeName:
Notice: Undefined property: DOMElement::$parentNode in
/home/olaf/test/test.php on line 22
parentNode:
------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/?id=36756&edit=1