MFH: fix #41692 (ArrayObject shows weird behaviour in respect to inheritance)

This commit is contained in:
Antony Dovgal 2007-06-27 12:30:28 +00:00
parent aa15254e41
commit f132df4f66
3 changed files with 57 additions and 11 deletions

2
NEWS
View File

@ -53,6 +53,8 @@ PHP NEWS
(Chris Jones, Tony) (Chris Jones, Tony)
- Fixed bug #41698 (float parameters truncated to integer in prepared - Fixed bug #41698 (float parameters truncated to integer in prepared
statements). (Ilia) statements). (Ilia)
- Fixed bug #41692 (ArrayObject shows weird behaviour in respect to
inheritance). (Tony)
- Fixed bug #41686 (Omitting length param in array_slice not possible). - Fixed bug #41686 (Omitting length param in array_slice not possible).
(Ilia) (Ilia)
- Fixed bug #41685 (array_push() fails to warn when next index is already - Fixed bug #41685 (array_push() fails to warn when next index is already

View File

@ -891,7 +891,7 @@ SPL_METHOD(Array, __construct)
{ {
zval *object = getThis(); zval *object = getThis();
spl_array_object *intern; spl_array_object *intern;
zval *array; zval **array;
long ar_flags = 0; long ar_flags = 0;
char *class_name; char *class_name;
int class_name_len; int class_name_len;
@ -904,11 +904,15 @@ SPL_METHOD(Array, __construct)
intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC); intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|ls", &array, &ar_flags, &class_name, &class_name_len) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|ls", &array, &ar_flags, &class_name, &class_name_len) == FAILURE) {
php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC); php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
return; return;
} }
if (Z_TYPE_PP(array) == IS_ARRAY) {
SEPARATE_ZVAL_IF_NOT_REF(array);
}
if (ZEND_NUM_ARGS() > 2) { if (ZEND_NUM_ARGS() > 2) {
if (zend_lookup_class(class_name, class_name_len, &pce_get_iterator TSRMLS_CC) == FAILURE) { if (zend_lookup_class(class_name, class_name_len, &pce_get_iterator TSRMLS_CC) == FAILURE) {
zend_throw_exception(spl_ce_InvalidArgumentException, "A class that implements Iterator must be specified", 0 TSRMLS_CC); zend_throw_exception(spl_ce_InvalidArgumentException, "A class that implements Iterator must be specified", 0 TSRMLS_CC);
@ -920,25 +924,25 @@ SPL_METHOD(Array, __construct)
ar_flags &= ~SPL_ARRAY_INT_MASK; ar_flags &= ~SPL_ARRAY_INT_MASK;
if (Z_TYPE_P(array) == IS_OBJECT && (Z_OBJ_HT_P(array) == &spl_handler_ArrayObject || Z_OBJ_HT_P(array) == &spl_handler_ArrayIterator)) { if (Z_TYPE_PP(array) == IS_OBJECT && (Z_OBJ_HT_PP(array) == &spl_handler_ArrayObject || Z_OBJ_HT_PP(array) == &spl_handler_ArrayIterator)) {
zval_ptr_dtor(&intern->array); zval_ptr_dtor(&intern->array);
if (ZEND_NUM_ARGS() == 1) if (ZEND_NUM_ARGS() == 1)
{ {
spl_array_object *other = (spl_array_object*)zend_object_store_get_object(array TSRMLS_CC); spl_array_object *other = (spl_array_object*)zend_object_store_get_object(*array TSRMLS_CC);
ar_flags = other->ar_flags & ~SPL_ARRAY_INT_MASK; ar_flags = other->ar_flags & ~SPL_ARRAY_INT_MASK;
} }
ar_flags |= SPL_ARRAY_USE_OTHER; ar_flags |= SPL_ARRAY_USE_OTHER;
intern->array = array; intern->array = *array;
} else { } else {
if (Z_TYPE_P(array) != IS_OBJECT && Z_TYPE_P(array) != IS_ARRAY) { if (Z_TYPE_PP(array) != IS_OBJECT && Z_TYPE_PP(array) != IS_ARRAY) {
php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC); php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
zend_throw_exception(spl_ce_InvalidArgumentException, "Passed variable is not an array or object, using empty array instead", 0 TSRMLS_CC); zend_throw_exception(spl_ce_InvalidArgumentException, "Passed variable is not an array or object, using empty array instead", 0 TSRMLS_CC);
return; return;
} }
zval_ptr_dtor(&intern->array); zval_ptr_dtor(&intern->array);
intern->array = array; intern->array = *array;
} }
if (object == array) { if (object == *array) {
intern->ar_flags |= SPL_ARRAY_IS_SELF; intern->ar_flags |= SPL_ARRAY_IS_SELF;
intern->ar_flags &= ~SPL_ARRAY_USE_OTHER; intern->ar_flags &= ~SPL_ARRAY_USE_OTHER;
} else { } else {
@ -946,12 +950,12 @@ SPL_METHOD(Array, __construct)
} }
intern->ar_flags |= ar_flags; intern->ar_flags |= ar_flags;
ZVAL_ADDREF(intern->array); ZVAL_ADDREF(intern->array);
if (Z_TYPE_P(array) == IS_OBJECT) { if (Z_TYPE_PP(array) == IS_OBJECT) {
zend_object_get_properties_t handler = Z_OBJ_HANDLER_P(array, get_properties); zend_object_get_properties_t handler = Z_OBJ_HANDLER_PP(array, get_properties);
if ((handler != std_object_handlers.get_properties && handler != spl_array_get_properties) if ((handler != std_object_handlers.get_properties && handler != spl_array_get_properties)
|| !spl_array_get_hash_table(intern, 0 TSRMLS_CC)) { || !spl_array_get_hash_table(intern, 0 TSRMLS_CC)) {
php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC); php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "Overloaded object of type %s is not compatible with %s", Z_OBJCE_P(array)->name, intern->std.ce->name); zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "Overloaded object of type %s is not compatible with %s", Z_OBJCE_PP(array)->name, intern->std.ce->name);
return; return;
} }
} }

View File

@ -0,0 +1,40 @@
--TEST--
Bug #41692 (ArrayObject shows weird behaviour in respect to inheritance)
--FILE--
<?php
class Bar extends ArrayObject {
private $foo = array( 1, 2, 3 );
function __construct()
{
parent::__construct($this->foo);
}
}
$foo = new Bar();
var_dump($foo);
$foo['foo'] = 23;
$bar = new Bar();
var_dump($bar);
echo "Done\n";
?>
--EXPECTF--
object(Bar)#%d (3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
object(Bar)#%d (3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
Done