]> granicus.if.org Git - php/commitdiff
MFH: fix #41692 (ArrayObject shows weird behaviour in respect to inheritance)
authorAntony Dovgal <tony2001@php.net>
Wed, 27 Jun 2007 12:30:28 +0000 (12:30 +0000)
committerAntony Dovgal <tony2001@php.net>
Wed, 27 Jun 2007 12:30:28 +0000 (12:30 +0000)
NEWS
ext/spl/spl_array.c
ext/spl/tests/bug41692.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index c14c0acb44c710f677815413a92b02d17b9c2bda..3a92f5854c09a11cd361b75fb2e17b37b292c740 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -53,6 +53,8 @@ PHP                                                                        NEWS
   (Chris Jones, Tony)
 - Fixed bug #41698 (float parameters truncated to integer in prepared 
   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).
   (Ilia)
 - Fixed bug #41685 (array_push() fails to warn when next index is already
index 456e63681a8d3bd30ecb861fe200b71ee7b114c8..6f6294526c2f73b24615883f4fb15f9d6c6b1893 100755 (executable)
@@ -891,7 +891,7 @@ SPL_METHOD(Array, __construct)
 {
        zval *object = getThis();
        spl_array_object *intern;
-       zval *array;
+       zval **array;
        long ar_flags = 0;
        char *class_name;
        int class_name_len;
@@ -904,11 +904,15 @@ SPL_METHOD(Array, __construct)
 
        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);
                return;
        }
 
+       if (Z_TYPE_PP(array) == IS_ARRAY) {
+               SEPARATE_ZVAL_IF_NOT_REF(array);
+       }
+
        if (ZEND_NUM_ARGS() > 2) {
                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);
@@ -920,25 +924,25 @@ SPL_METHOD(Array, __construct)
 
        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);
                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 |= SPL_ARRAY_USE_OTHER;
-               intern->array = array;
+               intern->array = *array;
        } 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);
                        zend_throw_exception(spl_ce_InvalidArgumentException, "Passed variable is not an array or object, using empty array instead", 0 TSRMLS_CC);
                        return;
                }
                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_USE_OTHER;
        } else {
@@ -946,12 +950,12 @@ SPL_METHOD(Array, __construct)
        }
        intern->ar_flags |= ar_flags;
        ZVAL_ADDREF(intern->array);
-       if (Z_TYPE_P(array) == IS_OBJECT) {
-               zend_object_get_properties_t handler = Z_OBJ_HANDLER_P(array, get_properties);
+       if (Z_TYPE_PP(array) == IS_OBJECT) {
+               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)
                || !spl_array_get_hash_table(intern, 0 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;
                }
        }
diff --git a/ext/spl/tests/bug41692.phpt b/ext/spl/tests/bug41692.phpt
new file mode 100644 (file)
index 0000000..8a2b958
--- /dev/null
@@ -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