diff options
| -rw-r--r-- | NEWS | 12 | ||||
| -rw-r--r-- | ext/spl/tests/bug70730.phpt | 44 | ||||
| -rw-r--r-- | ext/standard/var.c | 30 |
3 files changed, 67 insertions, 19 deletions
@@ -6,14 +6,18 @@ PHP NEWS . Fixed bug #70689 (Exception handler does not work as expected). (Laruence) . Fixed bug #70430 (Stack buffer overflow in zend_language_parser()). (Nikita) -- SOAP: - . Fixed bug #70715 (Segmentation fault inside soap client). (Laruence) - . Fixed bug #70709 (SOAP Client generates Segfault). (Laruence) - - Opcache: . Fixed bug #70724 (Undefined Symbols from opcache.so on Mac OS X 10.10). (Laruence) +- SPL: + . Fixed bug #70730 (Incorrect ArrayObject serialization if unset is called + in serialize()). (Laruence) + +- SOAP: + . Fixed bug #70715 (Segmentation fault inside soap client). (Laruence) + . Fixed bug #70709 (SOAP Client generates Segfault). (Laruence) + - XSL: . Fixed bug #70678 (PHP7 returns true when false is expected). (Felipe) diff --git a/ext/spl/tests/bug70730.phpt b/ext/spl/tests/bug70730.phpt new file mode 100644 index 0000000000..5710c9586d --- /dev/null +++ b/ext/spl/tests/bug70730.phpt @@ -0,0 +1,44 @@ +--TEST-- +Bug #70730 (Incorrect ArrayObject serialization if unset is called in serialize()) +--FILE-- +<?php +class A extends \ArrayObject +{ + protected $foo; + + public function __construct() + { + $this->foo = 'bar'; + } + + public function serialize() + { + unset($this->foo); + $result = parent::serialize(); + $this->foo = 'bar'; + return $result; + } +} + +$a = new A(); +$a->append('item1'); +$a->append('item2'); +$a->append('item3'); +$b = new A(); +$b->unserialize($a->serialize()); +var_dump($b); +?> +--EXPECTF-- +object(A)#%d (2) { + ["foo":protected]=> + string(3) "bar" + ["storage":"ArrayObject":private]=> + array(3) { + [0]=> + string(5) "item1" + [1]=> + string(5) "item2" + [2]=> + string(5) "item3" + } +} diff --git a/ext/standard/var.c b/ext/standard/var.c index 5de32f9c3e..72b2dd5ed5 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -35,7 +35,7 @@ #define COMMON (is_ref ? "&" : "") /* }}} */ -static uint32_t zend_hash_recalc_elements(HashTable *ht) /* {{{ */ +static uint32_t php_array_recalc_elements(HashTable *ht) /* {{{ */ { zval *val; uint32_t num = ht->nNumOfElements; @@ -52,12 +52,12 @@ static uint32_t zend_hash_recalc_elements(HashTable *ht) /* {{{ */ } /* }}} */ -static uint32_t zend_obj_num_elements(HashTable *ht) /* {{{ */ +static uint32_t php_array_num_elements(HashTable *ht) /* {{{ */ { uint32_t num = ht->nNumOfElements; if (UNEXPECTED(ht->u.v.flags & HASH_FLAG_HAS_EMPTY_IND)) { - num = zend_hash_recalc_elements(ht); + num = php_array_recalc_elements(ht); if (UNEXPECTED(ht->nNumOfElements == num)) { ht->u.v.flags &= ~HASH_FLAG_HAS_EMPTY_IND; } @@ -151,9 +151,9 @@ again: return; } if (UNEXPECTED(Z_SYMBOLTABLE_P(struc))) { - count = zend_hash_recalc_elements(myht); + count = php_array_recalc_elements(myht); } else { - count = zend_hash_num_elements(myht); + count = php_array_num_elements(myht); } php_printf("%sarray(%d) {\n", COMMON, count); is_temp = 0; @@ -182,7 +182,7 @@ again: myht = Z_OBJDEBUG_P(struc, is_temp); class_name = Z_OBJ_HANDLER_P(struc, get_class_name)(Z_OBJ_P(struc)); - php_printf("%sobject(%s)#%d (%d) {\n", COMMON, ZSTR_VAL(class_name), Z_OBJ_HANDLE_P(struc), myht ? zend_obj_num_elements(myht) : 0); + php_printf("%sobject(%s)#%d (%d) {\n", COMMON, ZSTR_VAL(class_name), Z_OBJ_HANDLE_P(struc), myht ? php_array_num_elements(myht) : 0); zend_string_release(class_name); if (myht) { @@ -325,9 +325,9 @@ again: return; } if (UNEXPECTED(Z_SYMBOLTABLE_P(struc))) { - count = zend_hash_recalc_elements(myht); + count = php_array_recalc_elements(myht); } else { - count = zend_hash_num_elements(myht); + count = php_array_num_elements(myht); } php_printf("%sarray(%d) refcount(%u){\n", COMMON, count, Z_REFCOUNTED_P(struc) ? Z_REFCOUNT_P(struc) : 1); ZEND_HASH_FOREACH_KEY_VAL_IND(myht, index, key, val) { @@ -356,7 +356,7 @@ again: } } class_name = Z_OBJ_HANDLER_P(struc, get_class_name)(Z_OBJ_P(struc)); - php_printf("%sobject(%s)#%d (%d) refcount(%u){\n", COMMON, ZSTR_VAL(class_name), Z_OBJ_HANDLE_P(struc), myht ? zend_obj_num_elements(myht) : 0, Z_REFCOUNT_P(struc)); + php_printf("%sobject(%s)#%d (%d) refcount(%u){\n", COMMON, ZSTR_VAL(class_name), Z_OBJ_HANDLE_P(struc), myht ? php_array_num_elements(myht) : 0, Z_REFCOUNT_P(struc)); zend_string_release(class_name); if (myht) { ZEND_HASH_FOREACH_KEY_VAL_IND(myht, index, key, val) { @@ -708,13 +708,13 @@ static void php_var_serialize_class(smart_str *buf, zval *struc, zval *retval_pt if (Z_TYPE_P(retval_ptr) == IS_ARRAY) { ht = Z_ARRVAL_P(retval_ptr); if (UNEXPECTED(Z_SYMBOLTABLE_P(struc))) { - count = zend_hash_recalc_elements(ht); + count = php_array_recalc_elements(ht); } else { - count = zend_hash_num_elements(ht); + count = php_array_num_elements(ht); } } else if (Z_TYPE_P(retval_ptr) == IS_OBJECT) { ht = Z_OBJPROP_P(retval_ptr); - count = zend_obj_num_elements(ht); + count = php_array_num_elements(ht); if (incomplete_class) { --count; } @@ -936,16 +936,16 @@ again: smart_str_appendl(buf, "a:", 2); myht = Z_ARRVAL_P(struc); if (UNEXPECTED(Z_SYMBOLTABLE_P(struc))) { - i = zend_hash_recalc_elements(myht); + i = php_array_recalc_elements(myht); } else { - i = zend_hash_num_elements(myht); + i = php_array_num_elements(myht); } } else { incomplete_class = php_var_serialize_class_name(buf, struc); myht = Z_OBJPROP_P(struc); /* count after serializing name, since php_var_serialize_class_name * changes the count if the variable is incomplete class */ - i = zend_obj_num_elements(myht); + i = php_array_num_elements(myht); if (i > 0 && incomplete_class) { --i; } |
