rrichards Fri Apr 8 11:58:24 2005 EDT
Added files:
/php-src/ext/dom/tests bug32615.phpt
Modified files:
/php-src/ext/dom node.c
Log:
- Fixed bug #32615 (Segfault in replaceChild() using fragment when
previousSibling is NULL)
- add test
http://cvs.php.net/diff.php/php-src/ext/dom/node.c?r1=1.32&r2=1.33&ty=u
Index: php-src/ext/dom/node.c
diff -u php-src/ext/dom/node.c:1.32 php-src/ext/dom/node.c:1.33
--- php-src/ext/dom/node.c:1.32 Fri Feb 18 06:47:20 2005
+++ php-src/ext/dom/node.c Fri Apr 8 11:58:22 2005
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: node.c,v 1.32 2005/02/18 11:47:20 rrichards Exp $ */
+/* $Id: node.c,v 1.33 2005/04/08 15:58:22 rrichards Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -856,7 +856,51 @@
/* }}} */
+static xmlNodePtr _php_dom_insert_fragment(xmlNodePtr nodep, xmlNodePtr
prevsib,
+ xmlNodePtr nextsib, xmlNodePtr
fragment,
+ dom_object *intern, dom_object
*childobj TSRMLS_DC)
+{
+ xmlNodePtr newchild, node;
+
+ newchild = fragment->children;
+
+ if (newchild) {
+ if (prevsib == NULL) {
+ nodep->children = newchild;
+ } else {
+ prevsib->next = newchild;
+ }
+ newchild->prev = prevsib;
+ if (nextsib == NULL) {
+ nodep->last = fragment->last;
+ } else {
+ fragment->last->next = nextsib;
+ nextsib->prev = fragment->last;
+ }
+
+ node = newchild;
+ while (node != NULL) {
+ node->parent = nodep;
+ if (node->doc != nodep->doc) {
+ xmlSetTreeDoc(node, nodep->doc);
+ if (node->_private != NULL) {
+ childobj = node->_private;
+ childobj->document = intern->document;
+
php_libxml_increment_doc_ref((php_libxml_node_object *)childobj, NULL
TSRMLS_CC);
+ }
+ }
+ if (node == fragment->last) {
+ break;
+ }
+ node = node->next;
+ }
+
+ fragment->children = NULL;
+ fragment->last = NULL;
+ }
+ return newchild;
+}
/* {{{ proto domnode dom_node_insert_before(DomNode newChild, DomNode
refChild);
URL:
http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-952280727
@@ -958,32 +1002,7 @@
}
}
} else if (child->type == XML_DOCUMENT_FRAG_NODE) {
- xmlNodePtr fragment;
-
- fragment = child;
- new_child = child->children;
- child = new_child;
- while (child->next != NULL) {
- child->parent = parentp;
- if (child->doc != parentp->doc) {
- xmlSetTreeDoc(child, parentp->doc);
- }
- child = child->next;
- }
- child->parent = parentp;
- if (child->doc != parentp->doc) {
- xmlSetTreeDoc(child, parentp->doc);
- }
-
- if (refp->prev != NULL) {
- refp->prev->next = new_child;
- } else {
- parentp->children = new_child;
- }
- new_child->prev = refp->prev;
- refp->prev = child;
- child->next = refp;
- fragment->children = NULL;
+ new_child = _php_dom_insert_fragment(parentp,
refp->prev, refp, child, intern, childobj TSRMLS_CC);
}
if (new_child == NULL) {
@@ -1025,32 +1044,7 @@
}
}
} else if (child->type == XML_DOCUMENT_FRAG_NODE) {
- xmlNodePtr fragment;
-
- fragment = child;
-
- new_child = child->children;
- if (parentp->children == NULL) {
- parentp->children = new_child;
- } else {
- child = parentp->last;
- child->next = new_child;
- new_child->prev = child;
- }
- child = new_child;
- while (child->next != NULL) {
- child->parent = parentp;
- if (child->doc != parentp->doc) {
- xmlSetTreeDoc(child, parentp->doc);
- }
- child = child->next;
- }
- child->parent = parentp;
- if (child->doc != parentp->doc) {
- xmlSetTreeDoc(child, parentp->doc);
- }
- parentp->last = child;
- fragment->children = NULL;
+ new_child = _php_dom_insert_fragment(parentp,
parentp->last, NULL, child, intern, childobj TSRMLS_CC);
}
if (new_child == NULL) {
new_child = xmlAddChild(parentp, child);
@@ -1133,50 +1127,14 @@
zval *rv = NULL;
if (newchild->type == XML_DOCUMENT_FRAG_NODE) {
- xmlNodePtr fragment, prevsib, nextsib;
- fragment = newchild;
+ xmlNodePtr prevsib, nextsib;
prevsib = oldchild->prev;
nextsib = oldchild->next;
- newchild = fragment->children;
-
xmlUnlinkNode(oldchild);
- if (prevsib == NULL && nextsib == NULL) {
- nodep->children = newchild;
- nodep->last = fragment->last;
- } else {
- if (newchild) {
- prevsib->next = newchild;
- newchild->prev = prevsib;
-
- fragment->last->next = nextsib;
- if (nextsib) {
- nextsib->prev = fragment->last;
- } else {
- nodep->last = fragment->last;
- }
- }
- }
- node = newchild;
- while (node != NULL) {
- node->parent = nodep;
- if (node->doc != nodep->doc) {
- xmlSetTreeDoc(node, nodep->doc);
- if (node->_private != NULL) {
- newchildobj = node->_private;
- newchildobj->document =
intern->document;
-
php_libxml_increment_doc_ref((php_libxml_node_object *)newchildobj, NULL
TSRMLS_CC);
- }
- }
- if (node == fragment->last) {
- break;
- }
- node = node->next;
- }
-
- fragment->children = NULL;
- fragment->last = NULL;
+ newchild = _php_dom_insert_fragment(nodep, prevsib,
nextsib, newchild, intern, newchildobj TSRMLS_CC);
+ dom_reconcile_ns(nodep->doc, newchild);
} else if (oldchild != newchild) {
if (newchild->doc == NULL && nodep->doc != NULL) {
xmlSetTreeDoc(newchild, nodep->doc);
@@ -1333,31 +1291,7 @@
}
}
} else if (child->type == XML_DOCUMENT_FRAG_NODE) {
- xmlNodePtr fragment;
-
- fragment = child;
- new_child = child->children;
- if (nodep->children == NULL) {
- nodep->children = new_child;
- } else {
- child = nodep->last;
- child->next = new_child;
- new_child->prev = child;
- }
- child = new_child;
- while (child->next != NULL) {
- child->parent = nodep;
- if (child->doc != nodep->doc) {
- xmlSetTreeDoc(child, nodep->doc);
- }
- child = child->next;
- }
- child->parent = nodep;
- if (child->doc != nodep->doc) {
- xmlSetTreeDoc(child, nodep->doc);
- }
- nodep->last = child;
- fragment->children = NULL;
+ new_child = _php_dom_insert_fragment(nodep, nodep->last, NULL,
child, intern, childobj TSRMLS_CC);
}
if (new_child == NULL) {
http://cvs.php.net/co.php/php-src/ext/dom/tests/bug32615.phpt?r=1.1&p=1
Index: php-src/ext/dom/tests/bug32615.phpt
+++ php-src/ext/dom/tests/bug32615.phpt
--TEST--
Bug # 32615: (Replacing and inserting Fragments)
--SKIPIF--
<?php require_once('skipif.inc'); ?>
--FILE--
<?php
$dom = new DomDocument;
$frag = $dom->createDocumentFragment();
$frag->appendChild(new DOMElement('root'));
$dom->appendChild($frag);
$root = $dom->documentElement;
$frag->appendChild(new DOMElement('first'));
$root->appendChild($frag);
$frag->appendChild(new DOMElement('second'));
$root->appendChild($frag);
$node = $dom->createElement('newfirst');
$frag->appendChild($node);
$root->replaceChild($frag, $root->firstChild);
unset($frag);
$frag = $dom->createDocumentFragment();
$frag->appendChild(new DOMElement('newsecond'));
$root->replaceChild($frag, $root->lastChild);
$node = $frag->appendChild(new DOMElement('fourth'));
$root->insertBefore($frag, NULL);
$frag->appendChild(new DOMElement('third'));
$node = $root->insertBefore($frag, $node);
$frag->appendChild(new DOMElement('start'));
$root->insertBefore($frag, $root->firstChild);
$frag->appendChild(new DOMElement('newthird'));
$root->replaceChild($frag, $node);
$frag->appendChild(new DOMElement('newfourth'));
$root->replaceChild($frag, $root->lastChild);
$frag->appendChild(new DOMElement('first'));
$root->replaceChild($frag, $root->firstChild->nextSibling);
$root->removeChild($root->firstChild);
echo $dom->saveXML()."\n";
while ($root->hasChildNodes()) {
$root->removeChild($root->firstChild);
}
$frag->appendChild(new DOMElement('first'));
$root->insertBefore($frag, $root->firstChild);
$node = $frag->appendChild(new DOMElement('fourth'));
$root->appendChild($frag);
$frag->appendChild(new DOMElement('second'));
$frag->appendChild(new DOMElement('third'));
$root->insertBefore($frag, $node);
echo $dom->saveXML();
?>
--EXPECT--
<?xml version="1.0"?>
<root><first/><newsecond/><newthird/><newfourth/></root>
<?xml version="1.0"?>
<root><first/><second/><third/><fourth/></root>
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php