Skip to content

Commit 6a79353

Browse files
committed
Merge branch 'PHP-8.1'
2 parents aa702c5 + c36a1ea commit 6a79353

File tree

5 files changed

+90
-2
lines changed

5 files changed

+90
-2
lines changed

NEWS

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@ PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? ????, PHP 8.2.0RC1
44

5+
- Core:
6+
. Fixed bug GH-9323 (Crash in ZEND_RETURN/GC/zend_call_function)
7+
(Tim Starling)
8+
9+
- DOM:
10+
. Fixed bug #79451 (Using DOMDocument->replaceChild on doctype causes
11+
double free) (NathanFreeman)
12+
13+
- Streams:
14+
. Fixed bug GH-9316 ($http_response_header is wrong for long status line).
15+
(cmb, timwolla)
516

617
18 Aug 2022, PHP 8.2.0beta3
718

Zend/zend_vm_def.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4320,6 +4320,7 @@ ZEND_VM_INLINE_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY, SPEC(OBSERVER))
43204320
zend_refcounted *ref = Z_COUNTED_P(retval_ptr);
43214321
ZVAL_COPY_VALUE(return_value, retval_ptr);
43224322
if (GC_MAY_LEAK(ref)) {
4323+
SAVE_OPLINE();
43234324
gc_possible_root(ref);
43244325
}
43254326
ZVAL_NULL(retval_ptr);
@@ -8425,8 +8426,8 @@ ZEND_VM_C_LABEL(check_indirect):
84258426
zend_refcounted *garbage = Z_COUNTED_P(variable_ptr);
84268427

84278428
ZVAL_REF(variable_ptr, ref);
8429+
SAVE_OPLINE();
84288430
if (GC_DELREF(garbage) == 0) {
8429-
SAVE_OPLINE();
84308431
rc_dtor_func(garbage);
84318432
if (UNEXPECTED(EG(exception))) {
84328433
ZVAL_NULL(variable_ptr);

Zend/zend_vm_execute.h

Lines changed: 11 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/dom/node.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#endif
2121

2222
#include "php.h"
23+
2324
#if defined(HAVE_LIBXML) && defined(HAVE_DOM)
2425
#include "php_dom.h"
2526

@@ -1003,6 +1004,7 @@ PHP_METHOD(DOMNode, replaceChild)
10031004
xmlNodePtr newchild, oldchild, nodep;
10041005
dom_object *intern, *newchildobj, *oldchildobj;
10051006
int stricterror;
1007+
bool replacedoctype = false;
10061008

10071009
int ret;
10081010

@@ -1042,7 +1044,51 @@ PHP_METHOD(DOMNode, replaceChild)
10421044
RETURN_FALSE;
10431045
}
10441046

1047+
<<<<<<< HEAD
10451048
if (oldchild->parent != nodep) {
1049+
=======
1050+
/* check for the old child and whether the new child is already a child */
1051+
while (children) {
1052+
if (children == oldchild) {
1053+
foundoldchild = 1;
1054+
break;
1055+
}
1056+
children = children->next;
1057+
}
1058+
1059+
if (foundoldchild) {
1060+
if (newchild->type == XML_DOCUMENT_FRAG_NODE) {
1061+
xmlNodePtr prevsib, nextsib;
1062+
prevsib = oldchild->prev;
1063+
nextsib = oldchild->next;
1064+
1065+
xmlUnlinkNode(oldchild);
1066+
1067+
newchild = _php_dom_insert_fragment(nodep, prevsib, nextsib, newchild, intern, newchildobj);
1068+
if (newchild) {
1069+
dom_reconcile_ns(nodep->doc, newchild);
1070+
}
1071+
} else if (oldchild != newchild) {
1072+
xmlDtdPtr intSubset = xmlGetIntSubset(nodep->doc);
1073+
replacedoctype = (intSubset == (xmlDtd *) oldchild);
1074+
1075+
if (newchild->doc == NULL && nodep->doc != NULL) {
1076+
xmlSetTreeDoc(newchild, nodep->doc);
1077+
newchildobj->document = intern->document;
1078+
php_libxml_increment_doc_ref((php_libxml_node_object *)newchildobj, NULL);
1079+
}
1080+
1081+
xmlReplaceNode(oldchild, newchild);
1082+
dom_reconcile_ns(nodep->doc, newchild);
1083+
1084+
if (replacedoctype) {
1085+
nodep->doc->intSubset = (xmlDtd *) newchild;
1086+
}
1087+
}
1088+
DOM_RET_OBJ(oldchild, &ret, intern);
1089+
return;
1090+
} else {
1091+
>>>>>>> PHP-8.0
10461092
php_dom_throw_error(NOT_FOUND_ERR, stricterror);
10471093
RETURN_FALSE;
10481094
}

ext/dom/tests/bug79451.phpt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
Bug #79451 (Using DOMDocument->replaceChild on doctype causes double free)
3+
--SKIPIF--
4+
<?php require_once('skipif.inc'); ?>
5+
--FILE--
6+
<?php
7+
$dom = new \DOMDocument();
8+
$dom->loadHTML("<!DOCTYPE html><p>hello</p>");
9+
$impl = new \DOMImplementation();
10+
$dt = $impl->createDocumentType("html_replace", "", "");
11+
$dom->replaceChild($dt, $dom->doctype);
12+
13+
var_dump($dom->doctype->name);
14+
echo $dom->saveXML();
15+
?>
16+
--EXPECTF--
17+
string(12) "html_replace"
18+
<?xml version="1.0" standalone="yes"?>
19+
<!DOCTYPE html_replace>
20+
<html><body><p>hello</p></body></html>

0 commit comments

Comments
 (0)