Skip to content

Commit 08c4db7

Browse files
committed
Fix manually calling __construct() on DOM classes
Closes GH-11894.
1 parent 5cd0208 commit 08c4db7

20 files changed

+312
-54
lines changed

NEWS

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ PHP NEWS
1717
. Fixed bug GH-11791 (Wrong default value of DOMDocument::xmlStandalone).
1818
(nielsdos)
1919
. Fix json_encode result on DOMDocument. (nielsdos)
20+
. Fix manually calling __construct() on DOM classes. (nielsdos)
2021

2122
- FFI:
2223
. Fix leaking definitions when using FFI::cdef()->new(...). (ilutov)

ext/dom/attr.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ PHP_METHOD(DOMAttr, __construct)
6262

6363
oldnode = dom_object_get_node(intern);
6464
if (oldnode != NULL) {
65-
php_libxml_node_free_resource(oldnode );
65+
php_libxml_node_decrement_resource((php_libxml_node_object *)intern);
6666
}
6767
php_libxml_increment_node_ptr((php_libxml_node_object *)intern, (xmlNodePtr)nodep, (void *)intern);
6868
}

ext/dom/cdatasection.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ PHP_METHOD(DOMCdataSection, __construct)
5252
intern = Z_DOMOBJ_P(ZEND_THIS);
5353
oldnode = dom_object_get_node(intern);
5454
if (oldnode != NULL) {
55-
php_libxml_node_free_resource(oldnode );
55+
php_libxml_node_decrement_resource((php_libxml_node_object *)intern);
5656
}
5757
php_libxml_increment_node_ptr((php_libxml_node_object *)intern, nodep, (void *)intern);
5858
}

ext/dom/comment.c

+4-6
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,11 @@ PHP_METHOD(DOMComment, __construct)
5050
}
5151

5252
intern = Z_DOMOBJ_P(ZEND_THIS);
53-
if (intern != NULL) {
54-
oldnode = dom_object_get_node(intern);
55-
if (oldnode != NULL) {
56-
php_libxml_node_free_resource(oldnode );
57-
}
58-
php_libxml_increment_node_ptr((php_libxml_node_object *)intern, (xmlNodePtr)nodep, (void *)intern);
53+
oldnode = dom_object_get_node(intern);
54+
if (oldnode != NULL) {
55+
php_libxml_node_decrement_resource((php_libxml_node_object *)intern);
5956
}
57+
php_libxml_increment_node_ptr((php_libxml_node_object *)intern, (xmlNodePtr)nodep, (void *)intern);
6058
}
6159
/* }}} end DOMComment::__construct */
6260

ext/dom/document.c

+12-14
Original file line numberDiff line numberDiff line change
@@ -1118,22 +1118,20 @@ PHP_METHOD(DOMDocument, __construct)
11181118
}
11191119

11201120
intern = Z_DOMOBJ_P(ZEND_THIS);
1121-
if (intern != NULL) {
1122-
olddoc = (xmlDocPtr) dom_object_get_node(intern);
1123-
if (olddoc != NULL) {
1124-
php_libxml_decrement_node_ptr((php_libxml_node_object *) intern);
1125-
refcount = php_libxml_decrement_doc_ref((php_libxml_node_object *)intern);
1126-
if (refcount != 0) {
1127-
olddoc->_private = NULL;
1128-
}
1129-
}
1130-
intern->document = NULL;
1131-
if (php_libxml_increment_doc_ref((php_libxml_node_object *)intern, docp) == -1) {
1132-
/* docp is always non-null so php_libxml_increment_doc_ref() never returns -1 */
1133-
ZEND_UNREACHABLE();
1121+
olddoc = (xmlDocPtr) dom_object_get_node(intern);
1122+
if (olddoc != NULL) {
1123+
php_libxml_decrement_node_ptr((php_libxml_node_object *) intern);
1124+
refcount = php_libxml_decrement_doc_ref((php_libxml_node_object *)intern);
1125+
if (refcount != 0) {
1126+
olddoc->_private = NULL;
11341127
}
1135-
php_libxml_increment_node_ptr((php_libxml_node_object *)intern, (xmlNodePtr)docp, (void *)intern);
11361128
}
1129+
intern->document = NULL;
1130+
if (php_libxml_increment_doc_ref((php_libxml_node_object *)intern, docp) == -1) {
1131+
/* docp is always non-null so php_libxml_increment_doc_ref() never returns -1 */
1132+
ZEND_UNREACHABLE();
1133+
}
1134+
php_libxml_increment_node_ptr((php_libxml_node_object *)intern, (xmlNodePtr)docp, (void *)intern);
11371135
}
11381136
/* }}} end DOMDocument::__construct */
11391137

ext/dom/documentfragment.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,8 @@ PHP_METHOD(DOMDocumentFragment, __construct)
5050
intern = Z_DOMOBJ_P(ZEND_THIS);
5151
oldnode = dom_object_get_node(intern);
5252
if (oldnode != NULL) {
53-
php_libxml_node_free_resource(oldnode );
53+
php_libxml_node_decrement_resource((php_libxml_node_object *)intern);
5454
}
55-
/* php_dom_set_object(intern, nodep); */
5655
php_libxml_increment_node_ptr((php_libxml_node_object *)intern, nodep, (void *)intern);
5756
}
5857
/* }}} end DOMDocumentFragment::__construct */

ext/dom/element.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ PHP_METHOD(DOMElement, __construct)
9797
intern = Z_DOMOBJ_P(ZEND_THIS);
9898
oldnode = dom_object_get_node(intern);
9999
if (oldnode != NULL) {
100-
php_libxml_node_free_resource(oldnode );
100+
php_libxml_node_decrement_resource((php_libxml_node_object *)intern);
101101
}
102102
php_libxml_increment_node_ptr((php_libxml_node_object *)intern, nodep, (void *)intern);
103103
}

ext/dom/entityreference.c

+4-6
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,11 @@ PHP_METHOD(DOMEntityReference, __construct)
5757
}
5858

5959
intern = Z_DOMOBJ_P(ZEND_THIS);
60-
if (intern != NULL) {
61-
oldnode = dom_object_get_node(intern);
62-
if (oldnode != NULL) {
63-
php_libxml_node_free_resource(oldnode );
64-
}
65-
php_libxml_increment_node_ptr((php_libxml_node_object *)intern, node, (void *)intern);
60+
oldnode = dom_object_get_node(intern);
61+
if (oldnode != NULL) {
62+
php_libxml_node_decrement_resource((php_libxml_node_object *)intern);
6663
}
64+
php_libxml_increment_node_ptr((php_libxml_node_object *)intern, node, (void *)intern);
6765
}
6866
/* }}} end DOMEntityReference::__construct */
6967

ext/dom/processinginstruction.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ PHP_METHOD(DOMProcessingInstruction, __construct)
5959
intern = Z_DOMOBJ_P(ZEND_THIS);
6060
oldnode = dom_object_get_node(intern);
6161
if (oldnode != NULL) {
62-
php_libxml_node_free_resource(oldnode );
62+
php_libxml_node_decrement_resource((php_libxml_node_object *)intern);
6363
}
6464
php_libxml_increment_node_ptr((php_libxml_node_object *)intern, nodep, (void *)intern);
6565
}

ext/dom/tests/DOMDocumentFragment_construct_basic_002.phpt

-16
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
--TEST--
2+
Manually call __construct() - attribute variation
3+
--EXTENSIONS--
4+
dom
5+
--FILE--
6+
<?php
7+
8+
$attr = new DOMAttr("attribute", "my value");
9+
var_dump($attr->nodeName, $attr->nodeValue);
10+
$attr->__construct("newattribute", "my new value");
11+
var_dump($attr->nodeName, $attr->nodeValue);
12+
13+
$doc = new DOMDocument();
14+
$doc->loadXML(<<<XML
15+
<?xml version="1.0"?>
16+
<container/>
17+
XML);
18+
$doc->documentElement->setAttributeNode($attr);
19+
echo $doc->saveXML();
20+
21+
$attr->__construct("newnewattribute", "my even newer value");
22+
$doc->documentElement->setAttributeNode($attr);
23+
echo $doc->saveXML();
24+
25+
?>
26+
--EXPECT--
27+
string(9) "attribute"
28+
string(8) "my value"
29+
string(12) "newattribute"
30+
string(12) "my new value"
31+
<?xml version="1.0"?>
32+
<container newattribute="my new value"/>
33+
<?xml version="1.0"?>
34+
<container newattribute="my new value" newnewattribute="my even newer value"/>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
--TEST--
2+
Manually call __construct() - CDATA section variation
3+
--EXTENSIONS--
4+
dom
5+
--FILE--
6+
<?php
7+
8+
$cdata = new DOMCdataSection("my value");
9+
var_dump($cdata->nodeValue);
10+
$cdata->__construct("my new value");
11+
var_dump($cdata->nodeValue);
12+
13+
$doc = new DOMDocument();
14+
$doc->loadXML(<<<XML
15+
<?xml version="1.0"?>
16+
<container/>
17+
XML);
18+
$doc->documentElement->appendChild($cdata);
19+
echo $doc->saveXML();
20+
21+
$cdata->__construct("my even newer value");
22+
$doc->documentElement->appendChild($cdata);
23+
echo $doc->saveXML();
24+
25+
?>
26+
--EXPECT--
27+
string(8) "my value"
28+
string(12) "my new value"
29+
<?xml version="1.0"?>
30+
<container><![CDATA[my new value]]></container>
31+
<?xml version="1.0"?>
32+
<container><![CDATA[my new value]]><![CDATA[my even newer value]]></container>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
--TEST--
2+
Manually call __construct() - comment variation
3+
--EXTENSIONS--
4+
dom
5+
--FILE--
6+
<?php
7+
8+
$comment = new DOMComment("my value");
9+
var_dump($comment->nodeName, $comment->nodeValue);
10+
$comment->__construct("my new value");
11+
var_dump($comment->nodeName, $comment->nodeValue);
12+
13+
$doc = new DOMDocument();
14+
$doc->loadXML(<<<XML
15+
<?xml version="1.0"?>
16+
<container/>
17+
XML);
18+
$doc->documentElement->appendChild($comment);
19+
echo $doc->saveXML();
20+
21+
$comment->__construct("my even newer value");
22+
$doc->documentElement->appendChild($comment);
23+
echo $doc->saveXML();
24+
25+
?>
26+
--EXPECT--
27+
string(8) "#comment"
28+
string(8) "my value"
29+
string(8) "#comment"
30+
string(12) "my new value"
31+
<?xml version="1.0"?>
32+
<container><!--my new value--></container>
33+
<?xml version="1.0"?>
34+
<container><!--my new value--><!--my even newer value--></container>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--TEST--
2+
Manually call __construct() - document variation
3+
--EXTENSIONS--
4+
dom
5+
--FILE--
6+
<?php
7+
8+
$doc = new DOMDocument();
9+
$doc->loadXML('<?xml version="1.0"?><foo/>');
10+
$doc->__construct("1.1", "UTF-8");
11+
echo $doc->saveXML();
12+
13+
?>
14+
--EXPECT--
15+
<?xml version="1.1" encoding="UTF-8"?>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
--TEST--
2+
Manually call __construct() - document fragment variation
3+
--EXTENSIONS--
4+
dom
5+
--FILE--
6+
<?php
7+
8+
$fragment = new DOMDocumentFragment();
9+
var_dump($fragment->textContent);
10+
$fragment->__construct();
11+
var_dump($fragment->textContent);
12+
13+
$doc = new DOMDocument();
14+
$doc->loadXML(<<<XML
15+
<?xml version="1.0"?>
16+
<container/>
17+
XML);
18+
@$doc->documentElement->appendChild($fragment);
19+
echo $doc->saveXML();
20+
21+
$fragment->__construct();
22+
@$doc->documentElement->appendChild($fragment);
23+
echo $doc->saveXML();
24+
25+
?>
26+
--EXPECT--
27+
string(0) ""
28+
string(0) ""
29+
<?xml version="1.0"?>
30+
<container/>
31+
<?xml version="1.0"?>
32+
<container/>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
--TEST--
2+
Manually call __construct() - element variation
3+
--EXTENSIONS--
4+
dom
5+
--FILE--
6+
<?php
7+
8+
$element = new DOMElement('foo', 'my value');
9+
var_dump($element->nodeName, $element->textContent);
10+
$element->__construct('foo2', 'my new value');
11+
var_dump($element->nodeName, $element->textContent);
12+
13+
$doc = new DOMDocument();
14+
$doc->loadXML(<<<XML
15+
<?xml version="1.0"?>
16+
<container/>
17+
XML);
18+
$doc->documentElement->appendChild($element);
19+
echo $doc->saveXML();
20+
21+
$element->__construct('foo3', 'my new new value');
22+
$doc->documentElement->appendChild($element);
23+
echo $doc->saveXML();
24+
25+
?>
26+
--EXPECT--
27+
string(3) "foo"
28+
string(8) "my value"
29+
string(4) "foo2"
30+
string(12) "my new value"
31+
<?xml version="1.0"?>
32+
<container><foo2>my new value</foo2></container>
33+
<?xml version="1.0"?>
34+
<container><foo2>my new value</foo2><foo3>my new new value</foo3></container>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
--TEST--
2+
Manually call __construct() - entity reference variation
3+
--EXTENSIONS--
4+
dom
5+
--FILE--
6+
<?php
7+
8+
$entityRef = new DOMEntityReference('foo');
9+
var_dump($entityRef->nodeName, $entityRef->textContent);
10+
$entityRef->__construct('foo2');
11+
var_dump($entityRef->nodeName, $entityRef->textContent);
12+
13+
$doc = new DOMDocument();
14+
$doc->loadXML(<<<XML
15+
<?xml version="1.0"?>
16+
<container/>
17+
XML);
18+
$doc->documentElement->appendChild($entityRef);
19+
echo $doc->saveXML();
20+
21+
$entityRef->__construct('foo3');
22+
$doc->documentElement->appendChild($entityRef);
23+
echo $doc->saveXML();
24+
25+
?>
26+
--EXPECT--
27+
string(3) "foo"
28+
string(0) ""
29+
string(4) "foo2"
30+
string(0) ""
31+
<?xml version="1.0"?>
32+
<container>&foo2;</container>
33+
<?xml version="1.0"?>
34+
<container>&foo2;&foo3;</container>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
--TEST--
2+
Manually call __construct() - processing instruction variation
3+
--EXTENSIONS--
4+
dom
5+
--FILE--
6+
<?php
7+
8+
$pi = new DOMProcessingInstruction('name1', 'value1');
9+
var_dump($pi->target, $pi->data);
10+
$pi->__construct('name2', 'value2');
11+
var_dump($pi->target, $pi->data);
12+
13+
$doc = new DOMDocument();
14+
$doc->loadXML(<<<XML
15+
<?xml version="1.0"?>
16+
<container/>
17+
XML);
18+
$doc->documentElement->appendChild($pi);
19+
echo $doc->saveXML();
20+
21+
$pi->__construct('name3', 'value3');
22+
$doc->documentElement->appendChild($pi);
23+
echo $doc->saveXML();
24+
25+
?>
26+
--EXPECT--
27+
string(5) "name1"
28+
string(6) "value1"
29+
string(5) "name2"
30+
string(6) "value2"
31+
<?xml version="1.0"?>
32+
<container><?name2 value2?></container>
33+
<?xml version="1.0"?>
34+
<container><?name2 value2?><?name3 value3?></container>

0 commit comments

Comments
 (0)