From fd561505f4142730684eacaba6f0ac5f293a8f0e Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 24 Feb 2016 22:31:17 +0100 Subject: [PATCH] Fix construction of AO with overloaded object error a) Fix uses of zend_string in error message b) Don't assign the overloaded object as the backing storage, that sort of defeats the point. Instead leave the previous value. --- ext/spl/spl_array.c | 14 +++++----- ...Object_overloaded_object_incompatible.phpt | 27 +++++++++++++++++++ 2 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 ext/spl/tests/ArrayObject_overloaded_object_incompatible.phpt diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index 070df29852..685dd27092 100644 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -1094,13 +1094,13 @@ static void spl_array_set_array(zval *object, spl_array_object *intern, zval *ar 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; @@ -1114,11 +1114,13 @@ 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); - 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); } } diff --git a/ext/spl/tests/ArrayObject_overloaded_object_incompatible.phpt b/ext/spl/tests/ArrayObject_overloaded_object_incompatible.phpt new file mode 100644 index 0000000000..8c1121b8d0 --- /dev/null +++ b/ext/spl/tests/ArrayObject_overloaded_object_incompatible.phpt @@ -0,0 +1,27 @@ +--TEST-- +Objects with overloaded get_properties are incompatible with ArrayObject +--FILE-- +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) + } +} -- 2.40.0