]> granicus.if.org Git - php/commitdiff
Make necessary separation (it might be possible to fix this in a better way, but...
authorDmitry Stogov <dmitry@zend.com>
Fri, 25 Sep 2015 07:59:27 +0000 (10:59 +0300)
committerDmitry Stogov <dmitry@zend.com>
Fri, 25 Sep 2015 07:59:27 +0000 (10:59 +0300)
ext/spl/spl_array.c
ext/spl/tests/arrayObject___construct_basic7.phpt [new file with mode: 0644]

index faae6ef237afbde54d7d1575911551cbb9206da9..ead514d7cdc25a4e579bc839895cafd8d928332f 100644 (file)
@@ -1099,11 +1099,19 @@ static void spl_array_set_array(zval *object, spl_array_object *intern, zval *ar
                        }
                } else {
                        zend_object_get_properties_t handler = Z_OBJ_HANDLER_P(array, get_properties);
-                       ZVAL_COPY(&intern->array, array);
                        if (handler != std_object_handlers.get_properties
                                || !spl_array_get_hash_table(intern, 0)) {
+                               ZVAL_UNDEF(&intern->array);
                                zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Overloaded object of type %s is not compatible with %s", Z_OBJCE_P(array)->name, intern->std.ce->name);
                        }
+                       //??? TODO: try to avoid array duplication
+                       if (Z_OBJ_P(array)->properties && GC_REFCOUNT(Z_OBJ_P(array)->properties) > 1) {
+                               if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array)->properties) & IS_ARRAY_IMMUTABLE))) {
+                                       GC_REFCOUNT(Z_OBJ_P(array)->properties)--;
+                               }
+                               Z_OBJ_P(array)->properties = zend_array_dup(Z_OBJ_P(array)->properties);
+                       }
+                       ZVAL_COPY(&intern->array, array);
                }
        }
 
diff --git a/ext/spl/tests/arrayObject___construct_basic7.phpt b/ext/spl/tests/arrayObject___construct_basic7.phpt
new file mode 100644 (file)
index 0000000..2474b38
--- /dev/null
@@ -0,0 +1,34 @@
+--TEST--
+SPL: ArrayObject::__construct: Using object with shared properties
+--FILE--
+<?php
+$y = 2;
+$x = 1;
+$a = array($y, $x);
+$o = (object)$a;
+$ao = new ArrayObject($o);
+$ao->asort();
+var_dump($a, $o, $ao);
+?>
+--EXPECT--
+array(2) {
+  [0]=>
+  int(2)
+  [1]=>
+  int(1)
+}
+object(stdClass)#1 (2) {
+  [1]=>
+  int(1)
+  [0]=>
+  int(2)
+}
+object(ArrayObject)#2 (1) {
+  ["storage":"ArrayObject":private]=>
+  object(stdClass)#1 (2) {
+    [1]=>
+    int(1)
+    [0]=>
+    int(2)
+  }
+}