Skip to content

Commit 4863d93

Browse files
committed
Merge branch 'PHP-8.2'
* 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
2 parents 69a8b63 + 57ff1c3 commit 4863d93

File tree

4 files changed

+96
-9
lines changed

4 files changed

+96
-9
lines changed

ext/dom/parentnode.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,15 @@ xmlNode* dom_zvals_to_fragment(php_libxml_ref_obj *document, xmlNode *contextNod
182182
goto err;
183183
}
184184

185-
if (newNode->parent != NULL) {
185+
if (newNode->type == XML_DOCUMENT_FRAG_NODE) {
186+
/* Unpack document fragment nodes, the behaviour differs for different libxml2 versions. */
187+
newNode = newNode->children;
188+
if (UNEXPECTED(newNode == NULL)) {
189+
/* No nodes to add, nothing to do here */
190+
continue;
191+
}
192+
xmlUnlinkNode(newNode);
193+
} else if (newNode->parent != NULL) {
186194
xmlUnlinkNode(newNode);
187195
}
188196

@@ -371,7 +379,7 @@ static void dom_pre_insert(xmlNodePtr insertion_point, xmlNodePtr parentNode, xm
371379
insertion_point->prev->next = newchild;
372380
newchild->prev = insertion_point->prev;
373381
}
374-
insertion_point->prev = newchild;
382+
insertion_point->prev = fragment->last;
375383
if (parentNode->children == insertion_point) {
376384
parentNode->children = newchild;
377385
}
@@ -565,15 +573,15 @@ void dom_child_replace_with(dom_object *context, zval *nodes, uint32_t nodesc)
565573
xmlNodePtr newchild = fragment->children;
566574
xmlDocPtr doc = parentNode->doc;
567575

576+
/* Unlink it unless it became a part of the fragment.
577+
* Freeing will be taken care of by the lifetime of the returned dom object. */
578+
if (child->parent != fragment) {
579+
xmlUnlinkNode(child);
580+
}
581+
568582
if (newchild) {
569583
xmlNodePtr last = fragment->last;
570584

571-
/* Unlink it unless it became a part of the fragment.
572-
* Freeing will be taken care of by the lifetime of the returned dom object. */
573-
if (child->parent != fragment) {
574-
xmlUnlinkNode(child);
575-
}
576-
577585
dom_pre_insert(insertion_point, parentNode, newchild, fragment);
578586

579587
dom_fragment_assign_parent_node(parentNode, fragment);

ext/dom/tests/gh11625.phpt

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
--TEST--
2+
GH-11625 (DOMElement::replaceWith() doesn't replace node with DOMDocumentFragment but just deletes node or causes wrapping <></> depending on libxml2 version)
3+
--EXTENSIONS--
4+
dom
5+
--FILE--
6+
<?php
7+
8+
function test($mutator) {
9+
$html = <<<XML
10+
<body>
11+
<div></div><div></div>
12+
</body>
13+
XML;
14+
15+
$dom = new DOMDocument();
16+
$dom->loadXML($html);
17+
18+
$divs = iterator_to_array($dom->getElementsByTagName('div')->getIterator());
19+
$i = 0;
20+
foreach ($divs as $div) {
21+
$mutator($dom, $div, $i);
22+
echo $dom->saveHTML();
23+
$i++;
24+
}
25+
}
26+
27+
echo "--- Single replacement ---\n";
28+
29+
test(function($dom, $div, $i) {
30+
$fragment = $dom->createDocumentFragment();
31+
$fragment->appendXML("<p>Hi $i!</p>");
32+
$div->replaceWith($fragment);
33+
});
34+
35+
echo "--- Multiple replacement ---\n";
36+
37+
test(function($dom, $div, $i) {
38+
$fragment = $dom->createDocumentFragment();
39+
$fragment->appendXML("<p>Hi $i!</p>");
40+
$div->replaceWith($fragment, $dom->createElement('x'), "hello");
41+
});
42+
43+
echo "--- Empty fragment replacement ---\n";
44+
45+
test(function($dom, $div, $i) {
46+
$fragment = $dom->createDocumentFragment();
47+
$div->replaceWith($fragment);
48+
});
49+
50+
?>
51+
--EXPECT--
52+
--- Single replacement ---
53+
<body>
54+
<p>Hi 0!</p><div></div>
55+
</body>
56+
<body>
57+
<p>Hi 0!</p><p>Hi 1!</p>
58+
</body>
59+
--- Multiple replacement ---
60+
<body>
61+
<p>Hi 0!</p><x></x>hello<div></div>
62+
</body>
63+
<body>
64+
<p>Hi 0!</p><x></x>hello<p>Hi 1!</p><x></x>hello
65+
</body>
66+
--- Empty fragment replacement ---
67+
<body>
68+
<div></div>
69+
</body>
70+
<body>
71+
72+
</body>

ext/imap/tests/bug77020.phpt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,13 @@
22
Bug #77020 (null pointer dereference in imap_mail)
33
--EXTENSIONS--
44
imap
5+
--INI--
6+
sendmail_path="echo >/dev/null"
57
--FILE--
68
<?php
9+
// For Windows, set it to a string of length HOST_NAME_LEN (256) so the mail is not actually sent
10+
ini_set("SMTP", str_repeat("A", 256));
11+
712
@imap_mail('1', 1, NULL);
813
echo 'done'
914
?>

ext/standard/tests/general_functions/proc_nice_basic.phpt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ if ($exit_code !== 0) {
3030
$niceBefore = getNice($pid);
3131
proc_nice($delta);
3232
$niceAfter = getNice($pid);
33-
var_dump($niceBefore == ($niceAfter - $delta));
33+
// The maximum niceness level is 19, if the process is already running at a high niceness, it cannot be increased.
34+
// Decreasing is only possible for superusers.
35+
var_dump(min($niceBefore + $delta, 19) == $niceAfter);
3436
?>
3537
--EXPECT--
3638
bool(true)

0 commit comments

Comments
 (0)