Skip to content

Commit

Permalink
Merge branch 'PHP-8.2'
Browse files Browse the repository at this point in the history
* PHP-8.2:
  Fix GH-11630: proc_nice_basic.phpt only works at certain nice levels
  Fix GH-11629: bug77020.phpt tries to send mail
  Fix GH-11625: DOMElement::replaceWith() doesn't replace node with DOMDocumentFragment but just deletes node or causes wrapping <></> depending on libxml2 version
  • Loading branch information
nielsdos committed Jul 10, 2023
2 parents 69a8b63 + 57ff1c3 commit 4863d93
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 9 deletions.
24 changes: 16 additions & 8 deletions ext/dom/parentnode.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,15 @@ xmlNode* dom_zvals_to_fragment(php_libxml_ref_obj *document, xmlNode *contextNod
goto err;
}

if (newNode->parent != NULL) {
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) {
xmlUnlinkNode(newNode);
}

Expand Down Expand Up @@ -371,7 +379,7 @@ static void dom_pre_insert(xmlNodePtr insertion_point, xmlNodePtr parentNode, xm
insertion_point->prev->next = newchild;
newchild->prev = insertion_point->prev;
}
insertion_point->prev = newchild;
insertion_point->prev = fragment->last;
if (parentNode->children == insertion_point) {
parentNode->children = newchild;
}
Expand Down Expand Up @@ -565,15 +573,15 @@ void dom_child_replace_with(dom_object *context, zval *nodes, uint32_t nodesc)
xmlNodePtr newchild = fragment->children;
xmlDocPtr doc = parentNode->doc;

/* Unlink it unless it became a part of the fragment.
* Freeing will be taken care of by the lifetime of the returned dom object. */
if (child->parent != fragment) {
xmlUnlinkNode(child);
}

if (newchild) {
xmlNodePtr last = fragment->last;

/* Unlink it unless it became a part of the fragment.
* Freeing will be taken care of by the lifetime of the returned dom object. */
if (child->parent != fragment) {
xmlUnlinkNode(child);
}

dom_pre_insert(insertion_point, parentNode, newchild, fragment);

dom_fragment_assign_parent_node(parentNode, fragment);
Expand Down
72 changes: 72 additions & 0 deletions ext/dom/tests/gh11625.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
--TEST--
GH-11625 (DOMElement::replaceWith() doesn't replace node with DOMDocumentFragment but just deletes node or causes wrapping <></> depending on libxml2 version)
--EXTENSIONS--
dom
--FILE--
<?php

function test($mutator) {
$html = <<<XML
<body>
<div></div><div></div>
</body>
XML;

$dom = new DOMDocument();
$dom->loadXML($html);

$divs = iterator_to_array($dom->getElementsByTagName('div')->getIterator());
$i = 0;
foreach ($divs as $div) {
$mutator($dom, $div, $i);
echo $dom->saveHTML();
$i++;
}
}

echo "--- Single replacement ---\n";

test(function($dom, $div, $i) {
$fragment = $dom->createDocumentFragment();
$fragment->appendXML("<p>Hi $i!</p>");
$div->replaceWith($fragment);
});

echo "--- Multiple replacement ---\n";

test(function($dom, $div, $i) {
$fragment = $dom->createDocumentFragment();
$fragment->appendXML("<p>Hi $i!</p>");
$div->replaceWith($fragment, $dom->createElement('x'), "hello");
});

echo "--- Empty fragment replacement ---\n";

test(function($dom, $div, $i) {
$fragment = $dom->createDocumentFragment();
$div->replaceWith($fragment);
});

?>
--EXPECT--
--- Single replacement ---
<body>
<p>Hi 0!</p><div></div>
</body>
<body>
<p>Hi 0!</p><p>Hi 1!</p>
</body>
--- Multiple replacement ---
<body>
<p>Hi 0!</p><x></x>hello<div></div>
</body>
<body>
<p>Hi 0!</p><x></x>hello<p>Hi 1!</p><x></x>hello
</body>
--- Empty fragment replacement ---
<body>
<div></div>
</body>
<body>

</body>
5 changes: 5 additions & 0 deletions ext/imap/tests/bug77020.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@
Bug #77020 (null pointer dereference in imap_mail)
--EXTENSIONS--
imap
--INI--
sendmail_path="echo >/dev/null"
--FILE--
<?php
// For Windows, set it to a string of length HOST_NAME_LEN (256) so the mail is not actually sent
ini_set("SMTP", str_repeat("A", 256));

@imap_mail('1', 1, NULL);
echo 'done'
?>
Expand Down
4 changes: 3 additions & 1 deletion ext/standard/tests/general_functions/proc_nice_basic.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ if ($exit_code !== 0) {
$niceBefore = getNice($pid);
proc_nice($delta);
$niceAfter = getNice($pid);
var_dump($niceBefore == ($niceAfter - $delta));
// The maximum niceness level is 19, if the process is already running at a high niceness, it cannot be increased.
// Decreasing is only possible for superusers.
var_dump(min($niceBefore + $delta, 19) == $niceAfter);
?>
--EXPECT--
bool(true)

0 comments on commit 4863d93

Please sign in to comment.