php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #36756 DOMDocument::removeChild corrupts node
Submitted: 2006-03-16 09:47 UTC Modified: 2006-03-18 12:48 UTC
From: olaf at 7val dot com Assigned: rrichards
Status: Closed Package: DOM XML related
PHP Version: 5.1.2 OS: Linux
Private report: No CVE-ID:
 [2006-03-16 09:47 UTC] 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: 

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-03-16 11:20 UTC] 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 11:39 UTC] 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 12:24 UTC] 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-18 12:48 UTC] rrichards@php.net
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.
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Sun Apr 20 20:02:01 2014 UTC