Skip to content

Commit 3253e61

Browse files
committed
Merge branch 'master' into sccp
* master: Revert "Fixed bug #74878" Upgrading note for #74837 Fixed bug #74837 - NEWS Implement Countable for DomNodeList and DOMNamedNodeMap (Request #74837) Fix #49649 - Handle property visibility changes on unserialization
2 parents e7f69f0 + 161c378 commit 3253e61

13 files changed

+305
-14
lines changed

NEWS

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,17 @@ PHP NEWS
99
unserialize). (Nikita)
1010
. Fixed bug #74819 (wddx_deserialize() heap out-of-bound read via
1111
php_parse_date()). (Derick)
12-
. Fixed bug #74878 (Data race in ZTS builds). (Nikita)
12+
. Fixed bug #49649 (unserialize() doesn't handle changes in property
13+
visibility). (pmmaga)
1314

1415
- Date:
1516
. Fixed bug #74852 (property_exists returns true on unknown DateInterval
1617
property). (jhdxr)
1718

19+
- DOM:
20+
. Implement #74837 (Implement Countable for DomNodeList and DOMNamedNodeMap).
21+
(Andreas Treichel)
22+
1823
- EXIF:
1924
. Deprecated the read_exif_data() alias. (Kalle)
2025
. Fixed bug #74428 (exif_read_data(): "Illegal IFD size" warning occurs with

UPGRADING

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,10 @@ See also: https://wiki.php.net/rfc/deprecations_php_7_2
224224
. Added stream_isatty().
225225
. Added sapi_windows_vt100_support().
226226

227+
- DOM:
228+
. DomNodeList implements Countable, added DomNodeList::count().
229+
. DOMNamedNodeMap implements Countable, added DOMNamedNodeMap::count().
230+
227231
- GD:
228232
. Added imagesetclip() and imagegetclip().
229233
. Added imageopenpolygon().

Zend/zend_API.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3742,10 +3742,6 @@ ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, z
37423742
break;
37433743
}
37443744
}
3745-
3746-
/* Must be interned to avoid ZTS data races */
3747-
name = zend_new_interned_string(zend_string_copy(name));
3748-
37493745
if (access_type & ZEND_ACC_PUBLIC) {
37503746
property_info->name = zend_string_copy(name);
37513747
} else if (access_type & ZEND_ACC_PRIVATE) {

ext/dom/dom_fe.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ PHP_METHOD(domnode, getLineNo);
172172

173173
/* domnodelist methods */
174174
PHP_FUNCTION(dom_nodelist_item);
175+
PHP_FUNCTION(dom_nodelist_count);
175176

176177
/* domnamednodemap methods */
177178
PHP_FUNCTION(dom_namednodemap_get_named_item);
@@ -181,6 +182,7 @@ PHP_FUNCTION(dom_namednodemap_item);
181182
PHP_FUNCTION(dom_namednodemap_get_named_item_ns);
182183
PHP_FUNCTION(dom_namednodemap_set_named_item_ns);
183184
PHP_FUNCTION(dom_namednodemap_remove_named_item_ns);
185+
PHP_FUNCTION(dom_namednodemap_count);
184186

185187
/* domcharacterdata methods */
186188
PHP_FUNCTION(dom_characterdata_substring_data);

ext/dom/namednodemap.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_namednodemap_remove_named_item_ns, 0, 0, 0)
5757
ZEND_ARG_INFO(0, namespaceURI)
5858
ZEND_ARG_INFO(0, localName)
5959
ZEND_END_ARG_INFO();
60+
61+
ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_namednodemap_count, 0, 0, 0)
62+
ZEND_END_ARG_INFO();
6063
/* }}} */
6164

6265
/*
@@ -74,6 +77,7 @@ const zend_function_entry php_dom_namednodemap_class_functions[] = { /* {{{ */
7477
PHP_FALIAS(getNamedItemNS, dom_namednodemap_get_named_item_ns, arginfo_dom_namednodemap_get_named_item_ns)
7578
PHP_FALIAS(setNamedItemNS, dom_namednodemap_set_named_item_ns, arginfo_dom_namednodemap_set_named_item_ns)
7679
PHP_FALIAS(removeNamedItemNS, dom_namednodemap_remove_named_item_ns, arginfo_dom_namednodemap_remove_named_item_ns)
80+
PHP_FALIAS(count, dom_namednodemap_count, arginfo_dom_namednodemap_count)
7781
PHP_FE_END
7882
};
7983
/* }}} */
@@ -332,6 +336,24 @@ PHP_FUNCTION(dom_namednodemap_remove_named_item_ns)
332336
}
333337
/* }}} end dom_namednodemap_remove_named_item_ns */
334338

339+
/* {{{ proto int|bool dom_namednodemap_count();
340+
*/
341+
PHP_FUNCTION(dom_namednodemap_count)
342+
{
343+
zval *id;
344+
dom_object *intern;
345+
346+
if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &id, dom_namednodemap_class_entry) == FAILURE) {
347+
return;
348+
}
349+
350+
intern = Z_DOMOBJ_P(id);
351+
if(dom_namednodemap_length_read(intern, return_value) == FAILURE) {
352+
RETURN_FALSE;
353+
}
354+
}
355+
/* }}} end dom_namednodemap_count */
356+
335357
#endif
336358

337359
/*

ext/dom/nodelist.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_nodelist_item, 0, 0, 1)
3434
ZEND_END_ARG_INFO();
3535
/* }}} */
3636

37+
/* {{{ arginfo */
38+
ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_nodelist_count, 0, 0, 0)
39+
ZEND_END_ARG_INFO();
40+
/* }}} */
41+
3742
/*
3843
* class DOMNodeList
3944
*
@@ -43,9 +48,11 @@ ZEND_END_ARG_INFO();
4348

4449
const zend_function_entry php_dom_nodelist_class_functions[] = {
4550
PHP_FALIAS(item, dom_nodelist_item, arginfo_dom_nodelist_item)
51+
PHP_FALIAS(count, dom_nodelist_count, arginfo_dom_nodelist_count)
4652
PHP_FE_END
4753
};
4854

55+
4956
/* {{{ length int
5057
readonly=yes
5158
URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-203510337
@@ -96,6 +103,25 @@ int dom_nodelist_length_read(dom_object *obj, zval *retval)
96103
return SUCCESS;
97104
}
98105

106+
107+
/* {{{ proto int|bool dom_nodelist_count();
108+
*/
109+
PHP_FUNCTION(dom_nodelist_count)
110+
{
111+
zval *id;
112+
dom_object *intern;
113+
114+
if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &id, dom_nodelist_class_entry) == FAILURE) {
115+
return;
116+
}
117+
118+
intern = Z_DOMOBJ_P(id);
119+
if(dom_nodelist_length_read(intern, return_value) == FAILURE) {
120+
RETURN_FALSE;
121+
}
122+
}
123+
/* }}} end dom_nodelist_count */
124+
99125
/* }}} */
100126

101127
/* {{{ proto DOMNode dom_nodelist_item(int index);
@@ -170,6 +196,7 @@ PHP_FUNCTION(dom_nodelist_item)
170196
}
171197
/* }}} end dom_nodelist_item */
172198

199+
173200
#endif
174201

175202
/*

ext/dom/php_dom.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -706,7 +706,7 @@ PHP_MINIT_FUNCTION(dom)
706706
ce.create_object = dom_nnodemap_objects_new;
707707
dom_nodelist_class_entry = zend_register_internal_class_ex(&ce, NULL);
708708
dom_nodelist_class_entry->get_iterator = php_dom_get_iterator;
709-
zend_class_implements(dom_nodelist_class_entry, 1, zend_ce_traversable);
709+
zend_class_implements(dom_nodelist_class_entry, 2, zend_ce_traversable, zend_ce_countable);
710710

711711
zend_hash_init(&dom_nodelist_prop_handlers, 0, NULL, dom_dtor_prop_handler, 1);
712712
dom_register_prop_handler(&dom_nodelist_prop_handlers, "length", sizeof("length")-1, dom_nodelist_length_read, NULL);
@@ -716,7 +716,7 @@ PHP_MINIT_FUNCTION(dom)
716716
ce.create_object = dom_nnodemap_objects_new;
717717
dom_namednodemap_class_entry = zend_register_internal_class_ex(&ce, NULL);
718718
dom_namednodemap_class_entry->get_iterator = php_dom_get_iterator;
719-
zend_class_implements(dom_namednodemap_class_entry, 1, zend_ce_traversable);
719+
zend_class_implements(dom_namednodemap_class_entry, 2, zend_ce_traversable, zend_ce_countable);
720720

721721
zend_hash_init(&dom_namednodemap_prop_handlers, 0, NULL, dom_dtor_prop_handler, 1);
722722
dom_register_prop_handler(&dom_namednodemap_prop_handlers, "length", sizeof("length")-1, dom_namednodemap_length_read, NULL);
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
--TEST--
2+
Test count nodes in DOMNamedNodeMap
3+
--CREDITS--
4+
Andreas Treichel <gmblar+github@gmail.com>
5+
--SKIPIF--
6+
<?php require_once('skipif.inc'); ?>
7+
--FILE--
8+
<?php
9+
10+
$document = new DomDocument();
11+
$root = $document->createElement('root');
12+
$document->appendChild($root);
13+
for($i = 0; $i < 5; $i++) {
14+
$root->setAttribute('attribute-' . $i, 'value-' . $i);
15+
}
16+
for($i = 0; $i < 7; $i++) {
17+
$item = $document->createElement('item');
18+
$root->appendChild($item);
19+
}
20+
var_dump($root->attributes->length);
21+
var_dump($root->attributes->count());
22+
var_dump(count($root->attributes));
23+
24+
?>
25+
--EXPECTF--
26+
int(5)
27+
int(5)
28+
int(5)

ext/dom/tests/DomNodeList_count.phpt

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
--TEST--
2+
Test count nodes in DOMNodeList
3+
--CREDITS--
4+
Andreas Treichel <gmblar+github@gmail.com>
5+
--SKIPIF--
6+
<?php require_once('skipif.inc'); ?>
7+
--FILE--
8+
<?php
9+
10+
$document = new DomDocument();
11+
$root = $document->createElement('root');
12+
$document->appendChild($root);
13+
for($i = 0; $i < 5; $i++) {
14+
$root->setAttribute('attribute-' . $i, 'value-' . $i);
15+
}
16+
for($i = 0; $i < 7; $i++) {
17+
$item = $document->createElement('item');
18+
$root->appendChild($item);
19+
}
20+
var_dump($root->childNodes->length);
21+
var_dump($root->childNodes->count());
22+
var_dump(count($root->childNodes));
23+
24+
?>
25+
--EXPECTF--
26+
int(7)
27+
int(7)
28+
int(7)
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
--TEST--
2+
Bug #49649 (unserialize() doesn't handle changes in property visibility) - to public
3+
--FILE--
4+
<?php
5+
6+
/**
7+
*class Foo
8+
*{
9+
* private $private = 1;
10+
*
11+
* protected $protected = 2;
12+
*
13+
* public $public = 3;
14+
*
15+
* public $notThere = 'old';
16+
* }
17+
*
18+
* echo base64_encode(serialize(new Foo()));
19+
*
20+
* The class above represents the serialized, base64_encoded string below.
21+
*/
22+
$serialized = 'TzozOiJGb28iOjQ6e3M6MTI6IgBGb28AcHJpdmF0ZSI7aToxO3M6MTI6IgAqAHByb3RlY3RlZCI7aToyO3M6NjoicHVibGljIjtpOjM7czo4OiJub3RUaGVyZSI7czozOiJvbGQiO30';
23+
24+
class Foo
25+
{
26+
public $public = null;
27+
28+
public $protected = null;
29+
30+
public $private = null;
31+
}
32+
33+
$class = unserialize(base64_decode($serialized));
34+
var_dump($class);
35+
--EXPECT--
36+
object(Foo)#1 (4) {
37+
["public"]=>
38+
int(3)
39+
["protected"]=>
40+
int(2)
41+
["private"]=>
42+
int(1)
43+
["notThere"]=>
44+
string(3) "old"
45+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
--TEST--
2+
Bug #49649 (unserialize() doesn't handle changes in property visibility) - to protected
3+
--FILE--
4+
<?php
5+
6+
/**
7+
*class Foo
8+
*{
9+
* private $private = 1;
10+
*
11+
* protected $protected = 2;
12+
*
13+
* public $public = 3;
14+
*
15+
* public $notThere = 'old';
16+
* }
17+
*
18+
* echo base64_encode(serialize(new Foo()));
19+
*
20+
* The class above represents the serialized, base64_encoded string below.
21+
*/
22+
$serialized = 'TzozOiJGb28iOjQ6e3M6MTI6IgBGb28AcHJpdmF0ZSI7aToxO3M6MTI6IgAqAHByb3RlY3RlZCI7aToyO3M6NjoicHVibGljIjtpOjM7czo4OiJub3RUaGVyZSI7czozOiJvbGQiO30';
23+
24+
class Foo
25+
{
26+
protected $public = null;
27+
28+
protected $protected = null;
29+
30+
protected $private = null;
31+
}
32+
33+
$class = unserialize(base64_decode($serialized));
34+
var_dump($class);
35+
--EXPECT--
36+
object(Foo)#1 (4) {
37+
["public":protected]=>
38+
int(3)
39+
["protected":protected]=>
40+
int(2)
41+
["private":protected]=>
42+
int(1)
43+
["notThere"]=>
44+
string(3) "old"
45+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
--TEST--
2+
Bug #49649 (unserialize() doesn't handle changes in property visibility) - to private
3+
--FILE--
4+
<?php
5+
6+
/**
7+
*class Foo
8+
*{
9+
* private $private = 1;
10+
*
11+
* protected $protected = 2;
12+
*
13+
* public $public = 3;
14+
*
15+
* public $notThere = 'old';
16+
* }
17+
*
18+
* echo base64_encode(serialize(new Foo()));
19+
*
20+
* The class above represents the serialized, base64_encoded string below.
21+
*/
22+
$serialized = 'TzozOiJGb28iOjQ6e3M6MTI6IgBGb28AcHJpdmF0ZSI7aToxO3M6MTI6IgAqAHByb3RlY3RlZCI7aToyO3M6NjoicHVibGljIjtpOjM7czo4OiJub3RUaGVyZSI7czozOiJvbGQiO30';
23+
24+
class Foo
25+
{
26+
private $public = null;
27+
28+
private $protected = null;
29+
30+
private $private = null;
31+
}
32+
33+
$class = unserialize(base64_decode($serialized));
34+
var_dump($class);
35+
--EXPECT--
36+
object(Foo)#1 (4) {
37+
["public":"Foo":private]=>
38+
int(3)
39+
["protected":"Foo":private]=>
40+
int(2)
41+
["private":"Foo":private]=>
42+
int(1)
43+
["notThere"]=>
44+
string(3) "old"
45+
}

0 commit comments

Comments
 (0)