1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

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
This commit is contained in:
Dmitry Stogov
2017-07-10 12:22:39 +03:00
13 changed files with 305 additions and 14 deletions

7
NEWS
View File

@@ -9,12 +9,17 @@ PHP NEWS
unserialize). (Nikita)
. Fixed bug #74819 (wddx_deserialize() heap out-of-bound read via
php_parse_date()). (Derick)
. Fixed bug #74878 (Data race in ZTS builds). (Nikita)
. Fixed bug #49649 (unserialize() doesn't handle changes in property
visibility). (pmmaga)
- Date:
. Fixed bug #74852 (property_exists returns true on unknown DateInterval
property). (jhdxr)
- DOM:
. Implement #74837 (Implement Countable for DomNodeList and DOMNamedNodeMap).
(Andreas Treichel)
- EXIF:
. Deprecated the read_exif_data() alias. (Kalle)
. Fixed bug #74428 (exif_read_data(): "Illegal IFD size" warning occurs with

View File

@@ -224,6 +224,10 @@ See also: https://wiki.php.net/rfc/deprecations_php_7_2
. Added stream_isatty().
. Added sapi_windows_vt100_support().
- DOM:
. DomNodeList implements Countable, added DomNodeList::count().
. DOMNamedNodeMap implements Countable, added DOMNamedNodeMap::count().
- GD:
. Added imagesetclip() and imagegetclip().
. Added imageopenpolygon().

View File

@@ -3742,10 +3742,6 @@ ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, z
break;
}
}
/* Must be interned to avoid ZTS data races */
name = zend_new_interned_string(zend_string_copy(name));
if (access_type & ZEND_ACC_PUBLIC) {
property_info->name = zend_string_copy(name);
} else if (access_type & ZEND_ACC_PRIVATE) {

View File

@@ -172,6 +172,7 @@ PHP_METHOD(domnode, getLineNo);
/* domnodelist methods */
PHP_FUNCTION(dom_nodelist_item);
PHP_FUNCTION(dom_nodelist_count);
/* domnamednodemap methods */
PHP_FUNCTION(dom_namednodemap_get_named_item);
@@ -181,6 +182,7 @@ PHP_FUNCTION(dom_namednodemap_item);
PHP_FUNCTION(dom_namednodemap_get_named_item_ns);
PHP_FUNCTION(dom_namednodemap_set_named_item_ns);
PHP_FUNCTION(dom_namednodemap_remove_named_item_ns);
PHP_FUNCTION(dom_namednodemap_count);
/* domcharacterdata methods */
PHP_FUNCTION(dom_characterdata_substring_data);

View File

@@ -57,6 +57,9 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_namednodemap_remove_named_item_ns, 0, 0, 0)
ZEND_ARG_INFO(0, namespaceURI)
ZEND_ARG_INFO(0, localName)
ZEND_END_ARG_INFO();
ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_namednodemap_count, 0, 0, 0)
ZEND_END_ARG_INFO();
/* }}} */
/*
@@ -74,6 +77,7 @@ const zend_function_entry php_dom_namednodemap_class_functions[] = { /* {{{ */
PHP_FALIAS(getNamedItemNS, dom_namednodemap_get_named_item_ns, arginfo_dom_namednodemap_get_named_item_ns)
PHP_FALIAS(setNamedItemNS, dom_namednodemap_set_named_item_ns, arginfo_dom_namednodemap_set_named_item_ns)
PHP_FALIAS(removeNamedItemNS, dom_namednodemap_remove_named_item_ns, arginfo_dom_namednodemap_remove_named_item_ns)
PHP_FALIAS(count, dom_namednodemap_count, arginfo_dom_namednodemap_count)
PHP_FE_END
};
/* }}} */
@@ -332,6 +336,24 @@ PHP_FUNCTION(dom_namednodemap_remove_named_item_ns)
}
/* }}} end dom_namednodemap_remove_named_item_ns */
/* {{{ proto int|bool dom_namednodemap_count();
*/
PHP_FUNCTION(dom_namednodemap_count)
{
zval *id;
dom_object *intern;
if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &id, dom_namednodemap_class_entry) == FAILURE) {
return;
}
intern = Z_DOMOBJ_P(id);
if(dom_namednodemap_length_read(intern, return_value) == FAILURE) {
RETURN_FALSE;
}
}
/* }}} end dom_namednodemap_count */
#endif
/*

View File

@@ -34,6 +34,11 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_nodelist_item, 0, 0, 1)
ZEND_END_ARG_INFO();
/* }}} */
/* {{{ arginfo */
ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_nodelist_count, 0, 0, 0)
ZEND_END_ARG_INFO();
/* }}} */
/*
* class DOMNodeList
*
@@ -43,9 +48,11 @@ ZEND_END_ARG_INFO();
const zend_function_entry php_dom_nodelist_class_functions[] = {
PHP_FALIAS(item, dom_nodelist_item, arginfo_dom_nodelist_item)
PHP_FALIAS(count, dom_nodelist_count, arginfo_dom_nodelist_count)
PHP_FE_END
};
/* {{{ length int
readonly=yes
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)
return SUCCESS;
}
/* {{{ proto int|bool dom_nodelist_count();
*/
PHP_FUNCTION(dom_nodelist_count)
{
zval *id;
dom_object *intern;
if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &id, dom_nodelist_class_entry) == FAILURE) {
return;
}
intern = Z_DOMOBJ_P(id);
if(dom_nodelist_length_read(intern, return_value) == FAILURE) {
RETURN_FALSE;
}
}
/* }}} end dom_nodelist_count */
/* }}} */
/* {{{ proto DOMNode dom_nodelist_item(int index);
@@ -170,6 +196,7 @@ PHP_FUNCTION(dom_nodelist_item)
}
/* }}} end dom_nodelist_item */
#endif
/*

View File

@@ -706,7 +706,7 @@ PHP_MINIT_FUNCTION(dom)
ce.create_object = dom_nnodemap_objects_new;
dom_nodelist_class_entry = zend_register_internal_class_ex(&ce, NULL);
dom_nodelist_class_entry->get_iterator = php_dom_get_iterator;
zend_class_implements(dom_nodelist_class_entry, 1, zend_ce_traversable);
zend_class_implements(dom_nodelist_class_entry, 2, zend_ce_traversable, zend_ce_countable);
zend_hash_init(&dom_nodelist_prop_handlers, 0, NULL, dom_dtor_prop_handler, 1);
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)
ce.create_object = dom_nnodemap_objects_new;
dom_namednodemap_class_entry = zend_register_internal_class_ex(&ce, NULL);
dom_namednodemap_class_entry->get_iterator = php_dom_get_iterator;
zend_class_implements(dom_namednodemap_class_entry, 1, zend_ce_traversable);
zend_class_implements(dom_namednodemap_class_entry, 2, zend_ce_traversable, zend_ce_countable);
zend_hash_init(&dom_namednodemap_prop_handlers, 0, NULL, dom_dtor_prop_handler, 1);
dom_register_prop_handler(&dom_namednodemap_prop_handlers, "length", sizeof("length")-1, dom_namednodemap_length_read, NULL);

View File

@@ -0,0 +1,28 @@
--TEST--
Test count nodes in DOMNamedNodeMap
--CREDITS--
Andreas Treichel <gmblar+github@gmail.com>
--SKIPIF--
<?php require_once('skipif.inc'); ?>
--FILE--
<?php
$document = new DomDocument();
$root = $document->createElement('root');
$document->appendChild($root);
for($i = 0; $i < 5; $i++) {
$root->setAttribute('attribute-' . $i, 'value-' . $i);
}
for($i = 0; $i < 7; $i++) {
$item = $document->createElement('item');
$root->appendChild($item);
}
var_dump($root->attributes->length);
var_dump($root->attributes->count());
var_dump(count($root->attributes));
?>
--EXPECTF--
int(5)
int(5)
int(5)

View File

@@ -0,0 +1,28 @@
--TEST--
Test count nodes in DOMNodeList
--CREDITS--
Andreas Treichel <gmblar+github@gmail.com>
--SKIPIF--
<?php require_once('skipif.inc'); ?>
--FILE--
<?php
$document = new DomDocument();
$root = $document->createElement('root');
$document->appendChild($root);
for($i = 0; $i < 5; $i++) {
$root->setAttribute('attribute-' . $i, 'value-' . $i);
}
for($i = 0; $i < 7; $i++) {
$item = $document->createElement('item');
$root->appendChild($item);
}
var_dump($root->childNodes->length);
var_dump($root->childNodes->count());
var_dump(count($root->childNodes));
?>
--EXPECTF--
int(7)
int(7)
int(7)

View File

@@ -0,0 +1,45 @@
--TEST--
Bug #49649 (unserialize() doesn't handle changes in property visibility) - to public
--FILE--
<?php
/**
*class Foo
*{
* private $private = 1;
*
* protected $protected = 2;
*
* public $public = 3;
*
* public $notThere = 'old';
* }
*
* echo base64_encode(serialize(new Foo()));
*
* The class above represents the serialized, base64_encoded string below.
*/
$serialized = 'TzozOiJGb28iOjQ6e3M6MTI6IgBGb28AcHJpdmF0ZSI7aToxO3M6MTI6IgAqAHByb3RlY3RlZCI7aToyO3M6NjoicHVibGljIjtpOjM7czo4OiJub3RUaGVyZSI7czozOiJvbGQiO30';
class Foo
{
public $public = null;
public $protected = null;
public $private = null;
}
$class = unserialize(base64_decode($serialized));
var_dump($class);
--EXPECT--
object(Foo)#1 (4) {
["public"]=>
int(3)
["protected"]=>
int(2)
["private"]=>
int(1)
["notThere"]=>
string(3) "old"
}

View File

@@ -0,0 +1,45 @@
--TEST--
Bug #49649 (unserialize() doesn't handle changes in property visibility) - to protected
--FILE--
<?php
/**
*class Foo
*{
* private $private = 1;
*
* protected $protected = 2;
*
* public $public = 3;
*
* public $notThere = 'old';
* }
*
* echo base64_encode(serialize(new Foo()));
*
* The class above represents the serialized, base64_encoded string below.
*/
$serialized = 'TzozOiJGb28iOjQ6e3M6MTI6IgBGb28AcHJpdmF0ZSI7aToxO3M6MTI6IgAqAHByb3RlY3RlZCI7aToyO3M6NjoicHVibGljIjtpOjM7czo4OiJub3RUaGVyZSI7czozOiJvbGQiO30';
class Foo
{
protected $public = null;
protected $protected = null;
protected $private = null;
}
$class = unserialize(base64_decode($serialized));
var_dump($class);
--EXPECT--
object(Foo)#1 (4) {
["public":protected]=>
int(3)
["protected":protected]=>
int(2)
["private":protected]=>
int(1)
["notThere"]=>
string(3) "old"
}

View File

@@ -0,0 +1,45 @@
--TEST--
Bug #49649 (unserialize() doesn't handle changes in property visibility) - to private
--FILE--
<?php
/**
*class Foo
*{
* private $private = 1;
*
* protected $protected = 2;
*
* public $public = 3;
*
* public $notThere = 'old';
* }
*
* echo base64_encode(serialize(new Foo()));
*
* The class above represents the serialized, base64_encoded string below.
*/
$serialized = 'TzozOiJGb28iOjQ6e3M6MTI6IgBGb28AcHJpdmF0ZSI7aToxO3M6MTI6IgAqAHByb3RlY3RlZCI7aToyO3M6NjoicHVibGljIjtpOjM7czo4OiJub3RUaGVyZSI7czozOiJvbGQiO30';
class Foo
{
private $public = null;
private $protected = null;
private $private = null;
}
$class = unserialize(base64_decode($serialized));
var_dump($class);
--EXPECT--
object(Foo)#1 (4) {
["public":"Foo":private]=>
int(3)
["protected":"Foo":private]=>
int(2)
["private":"Foo":private]=>
int(1)
["notThere"]=>
string(3) "old"
}

View File

@@ -427,14 +427,58 @@ numeric_key:
} else {
if (EXPECTED(Z_TYPE(key) == IS_STRING)) {
string_key:
if ((old_data = zend_hash_find(ht, Z_STR(key))) != NULL) {
if (Z_TYPE_P(old_data) == IS_INDIRECT) {
old_data = Z_INDIRECT_P(old_data);
{
zend_property_info *existing_propinfo;
zend_string *new_key, *unmangled;
const char *unmangled_class = NULL;
const char *unmangled_prop;
size_t unmangled_prop_len;
if (UNEXPECTED(zend_unmangle_property_name_ex(Z_STR(key), &unmangled_class, &unmangled_prop, &unmangled_prop_len) == FAILURE)) {
zval_dtor(&key);
return 0;
}
unmangled = zend_string_init(unmangled_prop, unmangled_prop_len, 0);
if (Z_TYPE_P(rval) == IS_OBJECT
&& ((existing_propinfo = zend_hash_find_ptr(&Z_OBJCE_P(rval)->properties_info, unmangled)) != NULL)
&& (existing_propinfo->flags & ZEND_ACC_PPP_MASK)) {
if (existing_propinfo->flags & ZEND_ACC_PROTECTED) {
new_key = zend_mangle_property_name(
"*", 1, ZSTR_VAL(unmangled), ZSTR_LEN(unmangled), Z_OBJCE_P(rval)->type & ZEND_INTERNAL_CLASS);
zend_string_release(unmangled);
} else if (existing_propinfo->flags & ZEND_ACC_PRIVATE) {
if (unmangled_class != NULL && strcmp(unmangled_class, "*") != 0) {
new_key = zend_mangle_property_name(
unmangled_class, strlen(unmangled_class),
ZSTR_VAL(unmangled), ZSTR_LEN(unmangled),
Z_OBJCE_P(rval)->type & ZEND_INTERNAL_CLASS);
} else {
new_key = zend_mangle_property_name(
ZSTR_VAL(existing_propinfo->ce->name), ZSTR_LEN(existing_propinfo->ce->name),
ZSTR_VAL(unmangled), ZSTR_LEN(unmangled),
Z_OBJCE_P(rval)->type & ZEND_INTERNAL_CLASS);
}
zend_string_release(unmangled);
} else {
ZEND_ASSERT(existing_propinfo->flags & ZEND_ACC_PUBLIC);
new_key = unmangled;
}
zend_string_release(Z_STR(key));
Z_STR(key) = new_key;
} else {
zend_string_release(unmangled);
}
if ((old_data = zend_hash_find(ht, Z_STR(key))) != NULL) {
if (Z_TYPE_P(old_data) == IS_INDIRECT) {
old_data = Z_INDIRECT_P(old_data);
}
var_push_dtor(var_hash, old_data);
data = zend_hash_update_ind(ht, Z_STR(key), &d);
} else {
data = zend_hash_add_new(ht, Z_STR(key), &d);
}
var_push_dtor(var_hash, old_data);
data = zend_hash_update_ind(ht, Z_STR(key), &d);
} else {
data = zend_hash_add_new(ht, Z_STR(key), &d);
}
} else if (Z_TYPE(key) == IS_LONG) {
/* object properties should include no integers */