mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2: Fix crash in ParentNode::append() when dealing with a fragment containing text nodes
This commit is contained in:
2
NEWS
2
NEWS
@@ -20,6 +20,8 @@ PHP NEWS
|
||||
. Fix references not handled correctly in C14N. (nielsdos)
|
||||
. Fix crash when calling childNodes next() when iterator is exhausted.
|
||||
(nielsdos)
|
||||
. Fix crash in ParentNode::append() when dealing with a fragment
|
||||
containing text nodes. (nielsdos)
|
||||
|
||||
- Hash:
|
||||
. ext/hash: Swap the checking order of `__has_builtin` and `__GNUC__`
|
||||
|
||||
@@ -146,6 +146,22 @@ static xmlDocPtr dom_doc_from_context_node(xmlNodePtr contextNode)
|
||||
}
|
||||
}
|
||||
|
||||
/* Citing from the docs (https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-tree.html#xmlAddChild):
|
||||
* "Add a new node to @parent, at the end of the child (or property) list merging adjacent TEXT nodes (in which case @cur is freed)".
|
||||
* So we must use a custom way of adding that does not merge. */
|
||||
static void dom_add_child_without_merging(xmlNodePtr parent, xmlNodePtr child)
|
||||
{
|
||||
if (parent->children == NULL) {
|
||||
parent->children = child;
|
||||
} else {
|
||||
xmlNodePtr last = parent->last;
|
||||
last->next = child;
|
||||
child->prev = last;
|
||||
}
|
||||
parent->last = child;
|
||||
child->parent = parent;
|
||||
}
|
||||
|
||||
xmlNode* dom_zvals_to_fragment(php_libxml_ref_obj *document, xmlNode *contextNode, zval *nodes, int nodesc)
|
||||
{
|
||||
xmlDoc *documentNode;
|
||||
@@ -178,7 +194,7 @@ xmlNode* dom_zvals_to_fragment(php_libxml_ref_obj *document, xmlNode *contextNod
|
||||
* So we must take a copy if this situation arises to prevent a use-after-free. */
|
||||
bool will_free = newNode->type == XML_TEXT_NODE && fragment->last && fragment->last->type == XML_TEXT_NODE;
|
||||
if (will_free) {
|
||||
newNode = xmlCopyNode(newNode, 1);
|
||||
newNode = xmlCopyNode(newNode, 0);
|
||||
}
|
||||
|
||||
if (newNode->type == XML_DOCUMENT_FRAG_NODE) {
|
||||
@@ -187,9 +203,7 @@ xmlNode* dom_zvals_to_fragment(php_libxml_ref_obj *document, xmlNode *contextNod
|
||||
while (newNode) {
|
||||
xmlNodePtr next = newNode->next;
|
||||
xmlUnlinkNode(newNode);
|
||||
if (!xmlAddChild(fragment, newNode)) {
|
||||
goto err;
|
||||
}
|
||||
dom_add_child_without_merging(fragment, newNode);
|
||||
newNode = next;
|
||||
}
|
||||
} else if (!xmlAddChild(fragment, newNode)) {
|
||||
|
||||
21
ext/dom/tests/ParentNode_append_fragment_text_coalesce.phpt
Normal file
21
ext/dom/tests/ParentNode_append_fragment_text_coalesce.phpt
Normal file
@@ -0,0 +1,21 @@
|
||||
--TEST--
|
||||
Text coalesce bug when appending fragment with text nodes
|
||||
--EXTENSIONS--
|
||||
dom
|
||||
--FILE--
|
||||
<?php
|
||||
$document = new DOMDocument();
|
||||
$document->loadXML('<root/>');
|
||||
|
||||
$sut = $document->createDocumentFragment();
|
||||
for($i = 0; $i < 10; $i++) {
|
||||
$textNode = $document->createTextNode("Node$i");
|
||||
$sut->append($textNode);
|
||||
}
|
||||
|
||||
$document->documentElement->append($sut);
|
||||
echo $document->saveXML();
|
||||
?>
|
||||
--EXPECT--
|
||||
<?xml version="1.0"?>
|
||||
<root>Node0Node1Node2Node3Node4Node5Node6Node7Node8Node9</root>
|
||||
Reference in New Issue
Block a user