return;
}
- zval_ptr_dtor(&intern->array);
-
if (Z_TYPE_P(array) == IS_ARRAY) {
//??? TODO: try to avoid array duplication
+ zval_ptr_dtor(&intern->array);
ZVAL_DUP(&intern->array, array);
} else {
if (Z_OBJ_HT_P(array) == &spl_handler_ArrayObject || Z_OBJ_HT_P(array) == &spl_handler_ArrayIterator) {
+ zval_ptr_dtor(&intern->array);
if (just_array) {
spl_array_object *other = Z_SPLARRAY_P(array);
ar_flags = other->ar_flags & ~SPL_ARRAY_INT_MASK;
}
} else {
zend_object_get_properties_t handler = Z_OBJ_HANDLER_P(array, get_properties);
- if (handler != std_object_handlers.get_properties
- || !spl_array_get_hash_table(intern)) {
- 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);
+ if (handler != std_object_handlers.get_properties) {
+ zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0,
+ "Overloaded object of type %s is not compatible with %s",
+ ZSTR_VAL(Z_OBJCE_P(array)->name), ZSTR_VAL(intern->std.ce->name));
+ return;
}
+ zval_ptr_dtor(&intern->array);
ZVAL_COPY(&intern->array, array);
}
}
--- /dev/null
+--TEST--
+Objects with overloaded get_properties are incompatible with ArrayObject
+--FILE--
+<?php
+
+$ao = new ArrayObject([1, 2, 3]);
+try {
+ $ao->exchangeArray(new SplFixedArray);
+} catch (Exception $e) {
+ echo $e->getMessage(), "\n";
+}
+var_dump($ao);
+
+?>
+--EXPECT--
+Overloaded object of type SplFixedArray is not compatible with ArrayObject
+object(ArrayObject)#1 (1) {
+ ["storage":"ArrayObject":private]=>
+ array(3) {
+ [0]=>
+ int(1)
+ [1]=>
+ int(2)
+ [2]=>
+ int(3)
+ }
+}