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

Reply via email to