diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 0c24aac48470a..6b6af2c225f79 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -3426,6 +3426,9 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c return; } } + } else if (prop_op_type == IS_CONST) { + /* CE mismatch, make cache slot consistent */ + cache_slot[0] = cache_slot[1] = cache_slot[2] = NULL; } /* Pointer on property callback is required */ diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 55d9647714d30..ed89c9d494a6f 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -4576,6 +4576,7 @@ static zval *date_interval_get_property_ptr_ptr(zend_object *object, zend_string zend_string_equals_literal(name, "days") || zend_string_equals_literal(name, "invert") ) { /* Fallback to read_property. */ + cache_slot[0] = cache_slot[1] = cache_slot[2] = NULL; ret = NULL; } else { ret = zend_std_get_property_ptr_ptr(object, name, type, cache_slot); @@ -4681,9 +4682,10 @@ static void php_date_interval_initialize_from_hash(zval **return_value, php_inte if (z_arg && Z_TYPE_P(z_arg) == IS_FALSE) { \ (*intobj)->diff->member = TIMELIB_UNSET; \ } else if (z_arg && Z_TYPE_P(z_arg) <= IS_STRING) { \ - zend_string *str = zval_get_string(z_arg); \ + zend_string *tmp_str; \ + zend_string *str = zval_get_tmp_string(z_arg, &tmp_str); \ DATE_A64I((*intobj)->diff->member, ZSTR_VAL(str)); \ - zend_string_release(str); \ + zend_tmp_string_release(tmp_str); \ } else { \ (*intobj)->diff->member = -1LL; \ } \ diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c index dd70d64826af2..6bcee1bc23e15 100644 --- a/ext/dom/php_dom.c +++ b/ext/dom/php_dom.c @@ -357,6 +357,7 @@ static zval *dom_get_property_ptr_ptr(zend_object *object, zend_string *name, in return zend_std_get_property_ptr_ptr(object, name, type, cache_slot); } + cache_slot[0] = cache_slot[1] = cache_slot[2] = NULL; return NULL; } diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c index 040c99ef42023..0ffded87c08a0 100644 --- a/ext/pdo/pdo_stmt.c +++ b/ext/pdo/pdo_stmt.c @@ -2388,6 +2388,7 @@ static zval *pdo_row_get_property_ptr_ptr(zend_object *object, zend_string *name ZEND_IGNORE_VALUE(type); ZEND_IGNORE_VALUE(cache_slot); + cache_slot[0] = cache_slot[1] = cache_slot[2] = NULL; return NULL; } diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c index 3dcf7ca8fb049..1de7ccc6e74e8 100644 --- a/ext/simplexml/simplexml.c +++ b/ext/simplexml/simplexml.c @@ -631,6 +631,8 @@ static zval *sxe_property_get_adr(zend_object *object, zend_string *zname, int f SXE_ITER type; zval member; + cache_slot[0] = cache_slot[1] = cache_slot[2] = NULL; + sxe = php_sxe_fetch_object(object); GET_NODE(sxe, node); if (UNEXPECTED(!node)) { diff --git a/ext/simplexml/tests/gh17736.phpt b/ext/simplexml/tests/gh17736.phpt new file mode 100644 index 0000000000000..78561f6ab0293 --- /dev/null +++ b/ext/simplexml/tests/gh17736.phpt @@ -0,0 +1,20 @@ +--TEST-- +GH-17736 (Assertion failure zend_reference_destroy()) +--EXTENSIONS-- +simplexml +--FILE-- +'); +class C { + public int $a = 1; +} +function test($obj) { + $ref =& $obj->a; +} +$obj = new C; +test($obj); +test($o1); +echo "Done\n"; +?> +--EXPECT-- +Done diff --git a/ext/snmp/snmp.c b/ext/snmp/snmp.c index abee491720851..33c8e58acdd1d 100644 --- a/ext/snmp/snmp.c +++ b/ext/snmp/snmp.c @@ -1921,6 +1921,7 @@ static zval *php_snmp_get_property_ptr_ptr(zend_object *object, zend_string *nam return zend_std_get_property_ptr_ptr(object, name, type, cache_slot); } + cache_slot[0] = cache_slot[1] = cache_slot[2] = NULL; return NULL; } diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index 5021bc441f945..3e386254b7e43 100644 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -861,6 +861,8 @@ static zval *spl_array_get_property_ptr_ptr(zend_object *object, zend_string *na if ((intern->ar_flags & SPL_ARRAY_ARRAY_AS_PROPS) != 0 && !zend_std_has_property(object, name, ZEND_PROPERTY_EXISTS, NULL)) { + cache_slot[0] = cache_slot[1] = cache_slot[2] = NULL; + /* If object has offsetGet() overridden, then fallback to read_property, * which will call offsetGet(). */ zval member; diff --git a/ext/xmlreader/php_xmlreader.c b/ext/xmlreader/php_xmlreader.c index 992d60bd2c2ec..9bc0af63a791e 100644 --- a/ext/xmlreader/php_xmlreader.c +++ b/ext/xmlreader/php_xmlreader.c @@ -113,10 +113,12 @@ static int xmlreader_property_reader(xmlreader_object *obj, xmlreader_prop_handl static zval *xmlreader_get_property_ptr_ptr(zend_object *object, zend_string *name, int type, void **cache_slot) { zval *retval = NULL; - xmlreader_prop_handler *hnd = zend_hash_find_ptr(&xmlreader_prop_handlers, name); + xmlreader_prop_handler *hnd = zend_hash_find_ptr(&xmlreader_prop_handlers, name); if (hnd == NULL) { retval = zend_std_get_property_ptr_ptr(object, name, type, cache_slot); + } else { + cache_slot[0] = cache_slot[1] = cache_slot[2] = NULL; } return retval; diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index 0e0f717f5aa38..65a835867f591 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -889,6 +889,8 @@ static zval *php_zip_get_property_ptr_ptr(zend_object *object, zend_string *name zval *retval = NULL; zip_prop_handler *hnd = NULL; + cache_slot[0] = cache_slot[1] = cache_slot[2] = NULL; + obj = php_zip_fetch_object(object); if (obj->prop_handler != NULL) {