mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Merge branch 'PHP-8.1' into PHP-8.2
* PHP-8.1: Handle fragments consisting out of multiple children without a single root correctly
This commit is contained in:
commit
f2ed2b877d
2 changed files with 53 additions and 15 deletions
|
@ -183,15 +183,7 @@ xmlNode* dom_zvals_to_fragment(php_libxml_ref_obj *document, xmlNode *contextNod
|
|||
goto err;
|
||||
}
|
||||
|
||||
if (newNode->type == XML_DOCUMENT_FRAG_NODE) {
|
||||
/* Unpack document fragment nodes, the behaviour differs for different libxml2 versions. */
|
||||
newNode = newNode->children;
|
||||
if (UNEXPECTED(newNode == NULL)) {
|
||||
/* No nodes to add, nothing to do here */
|
||||
continue;
|
||||
}
|
||||
xmlUnlinkNode(newNode);
|
||||
} else if (newNode->parent != NULL) {
|
||||
if (newNode->parent != NULL) {
|
||||
xmlUnlinkNode(newNode);
|
||||
}
|
||||
|
||||
|
@ -210,14 +202,23 @@ xmlNode* dom_zvals_to_fragment(php_libxml_ref_obj *document, xmlNode *contextNod
|
|||
newNode = xmlCopyNode(newNode, 1);
|
||||
}
|
||||
|
||||
if (!xmlAddChild(fragment, newNode)) {
|
||||
if (newNode->type == XML_DOCUMENT_FRAG_NODE) {
|
||||
/* Unpack document fragment nodes, the behaviour differs for different libxml2 versions. */
|
||||
newNode = newNode->children;
|
||||
while (newNode) {
|
||||
xmlNodePtr next = newNode->next;
|
||||
xmlUnlinkNode(newNode);
|
||||
if (!xmlAddChild(fragment, newNode)) {
|
||||
goto hierarchy_request_err;
|
||||
}
|
||||
newNode = next;
|
||||
}
|
||||
} else if (!xmlAddChild(fragment, newNode)) {
|
||||
if (will_free) {
|
||||
xmlFreeNode(newNode);
|
||||
}
|
||||
goto hierarchy_request_err;
|
||||
}
|
||||
|
||||
continue;
|
||||
} else {
|
||||
zend_argument_type_error(i + 1, "must be of type DOMNode|string, %s given", zend_zval_type_name(&nodes[i]));
|
||||
goto err;
|
||||
|
@ -363,14 +364,13 @@ static void dom_pre_insert(xmlNodePtr insertion_point, xmlNodePtr parentNode, xm
|
|||
/* Place it as last node */
|
||||
if (parentNode->children) {
|
||||
/* There are children */
|
||||
fragment->last->prev = parentNode->last;
|
||||
newchild->prev = parentNode->last->prev;
|
||||
newchild->prev = parentNode->last;
|
||||
parentNode->last->next = newchild;
|
||||
} else {
|
||||
/* No children, because they moved out when they became a fragment */
|
||||
parentNode->children = newchild;
|
||||
parentNode->last = newchild;
|
||||
}
|
||||
parentNode->last = fragment->last;
|
||||
} else {
|
||||
/* Insert fragment before insertion_point */
|
||||
fragment->last->next = insertion_point;
|
||||
|
|
38
ext/dom/tests/fragments_multiple_nodes_DOMParentNode.phpt
Normal file
38
ext/dom/tests/fragments_multiple_nodes_DOMParentNode.phpt
Normal file
|
@ -0,0 +1,38 @@
|
|||
--TEST--
|
||||
Handling fragments of multiple nodes for DOMParentNode
|
||||
--EXTENSIONS--
|
||||
dom
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$dom = new DOMDocument();
|
||||
$dom->loadXML('<!DOCTYPE HTML><html><container/></html>');
|
||||
|
||||
$container = $dom->documentElement->firstElementChild;
|
||||
|
||||
$fragment = $dom->createDocumentFragment();
|
||||
$fragment->appendChild($dom->createElement('p', '1'));
|
||||
$fragment->appendChild($dom->createElement('b', '2'));
|
||||
$container->replaceWith($fragment);
|
||||
echo $dom->saveXML();
|
||||
|
||||
$dom->documentElement->append('foo');
|
||||
echo $dom->saveXML();
|
||||
|
||||
$fragment = $dom->createDocumentFragment();
|
||||
$fragment->appendChild($dom->createElement('p', '3'));
|
||||
$fragment->appendChild($dom->createElement('b', '4'));
|
||||
$dom->documentElement->prepend($fragment);
|
||||
echo $dom->saveXML();
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE HTML>
|
||||
<html><p>1</p><b>2</b></html>
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE HTML>
|
||||
<html><p>1</p><b>2</b>foo</html>
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE HTML>
|
||||
<html><p>3</p><b>4</b><p>1</p><b>2</b>foo</html>
|
Loading…
Add table
Add a link
Reference in a new issue