From 4182813ebffe0570e3741debd7da543df3517d0d Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Fri, 30 Jun 2023 10:49:19 +0200 Subject: [PATCH] Call cast_object handler from get_properties_for Fixes GH-11547 Closes GH-11583 --- UPGRADING.INTERNALS | 2 ++ Zend/zend_object_handlers.c | 10 ++++++++++ ext/com_dotnet/com_handlers.c | 4 ++++ ext/simplexml/simplexml.c | 1 + 4 files changed, 17 insertions(+) diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index 1a8c5970c7f..4a3254b2353 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -70,6 +70,8 @@ PHP 8.3 INTERNALS UPGRADE NOTES * _php_stream_dirent now has an extra d_type field that is used to store the directory entry type. This can be used to avoid additional stat calls for types when the type is already known. +* zend_std_get_properties_for now calls the cast_object handler when casting + objects to arrays. ======================== 2. Build system changes diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index b18d0f46f80..1ff5ed63782 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -1975,6 +1975,16 @@ ZEND_API HashTable *zend_std_get_properties_for(zend_object *obj, zend_prop_purp } ZEND_FALLTHROUGH; case ZEND_PROP_PURPOSE_ARRAY_CAST: + if (obj->handlers->cast_object != std_object_handlers.cast_object) { + zval result; + if (obj->handlers->cast_object(obj, &result, IS_ARRAY) == SUCCESS) { + return Z_ARRVAL(result); + } + if (EG(exception)) { + return NULL; + } + } + ZEND_FALLTHROUGH; case ZEND_PROP_PURPOSE_SERIALIZE: case ZEND_PROP_PURPOSE_VAR_EXPORT: case ZEND_PROP_PURPOSE_JSON: diff --git a/ext/com_dotnet/com_handlers.c b/ext/com_dotnet/com_handlers.c index 0c73d8c4a3a..93b1c414b7c 100644 --- a/ext/com_dotnet/com_handlers.c +++ b/ext/com_dotnet/com_handlers.c @@ -431,6 +431,10 @@ static int com_objects_compare(zval *object1, zval *object2) static zend_result com_object_cast(zend_object *readobj, zval *writeobj, int type) { + if (type == IS_ARRAY) { + return FAILURE; + } + php_com_dotnet_object *obj; VARIANT v; VARTYPE vt = VT_EMPTY; diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c index 5d7137406be..6996474e49e 100644 --- a/ext/simplexml/simplexml.c +++ b/ext/simplexml/simplexml.c @@ -1819,6 +1819,7 @@ static zend_result cast_object(zval *object, int type, char *contents) convert_scalar_to_number(object); break; default: + zval_ptr_dtor_nogc(object); return FAILURE; } return SUCCESS;