From: Dmitry Stogov Date: Tue, 7 Jun 2005 07:03:20 +0000 (+0000) Subject: Fixed bug #33243 (ze1_compatibility_mode does not work as expected) X-Git-Tag: php-5.0.5RC1~198 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c8add6a3c249faf3c1d7ca5df6309400cf84e5fe;p=php Fixed bug #33243 (ze1_compatibility_mode does not work as expected) --- diff --git a/NEWS b/NEWS index 3601d9032c..e74785ecbe 100644 --- a/NEWS +++ b/NEWS @@ -14,6 +14,7 @@ PHP NEWS - Fixed memory corruption in ImageTTFText() with 64bit systems. (Andrey) - Fixed memory corruption in stristr(). (Derick) - Fixed segfaults when CURL callback functions throw exception. (Tony) +- Fixed bug #33243 (ze1_compatibility_mode does not work as expected). (Dmitry) - Fixed bug #33242 (Mangled error message when stream fails). (Derick) - Fixed bug #33222 (segfault when CURL handle is closed in a callback). (Tony) - Fixed bug #33214 (odbc_next_result does not signal SQL errors with diff --git a/Zend/tests/bug33243.phpt b/Zend/tests/bug33243.phpt new file mode 100755 index 0000000000..bb5d77c7bf --- /dev/null +++ b/Zend/tests/bug33243.phpt @@ -0,0 +1,25 @@ +--TEST-- +Bug #33243 (ze1_compatibility_mode does not work as expected) +--INI-- +zend.ze1_compatibility_mode=1 +error_reporting=4095 +--FILE-- +y->z = 0; +$b = $a; // should perform deep copy of $a +$b->y->z = 1; // hence this should have no effect on $a +var_dump($a); +?> +--EXPECTF-- +Strict Standards: Creating default object from empty value in %sbug33243.php on line 2 + +Strict Standards: Implicit cloning object of class 'stdClass' because of 'zend.ze1_compatibility_mode' in %sbug33243.php on line 3 + +Strict Standards: Implicit cloning object of class 'stdClass' because of 'zend.ze1_compatibility_mode' in %sbug33243.php on line 5 +object(stdClass)#%d (1) { + ["y"]=> + object(stdClass)#%d (1) { + ["z"]=> + int(0) + } +} diff --git a/Zend/zend_objects.c b/Zend/zend_objects.c index 162905256b..c37b54b47a 100644 --- a/Zend/zend_objects.c +++ b/Zend/zend_objects.c @@ -111,9 +111,31 @@ ZEND_API zend_object *zend_objects_get_address(zval *zobject TSRMLS_DC) return (zend_object *)zend_object_store_get_object(zobject TSRMLS_CC); } +static void zval_add_ref_or_clone(zval **p) +{ + if (Z_TYPE_PP(p) == IS_OBJECT) { + if (Z_OBJ_HANDLER_PP(p, clone_obj) == NULL) { + zend_error(E_ERROR, "Trying to clone an uncloneable object of class %s", Z_OBJCE_PP(p)->name); + } else { + zval *orig = *p; + + ALLOC_ZVAL(*p); + **p = *orig; + INIT_PZVAL(*p); + (*p)->value.obj = Z_OBJ_HT_PP(p)->clone_obj(*p TSRMLS_CC); + } + } else { + (*p)->refcount++; + } +} + ZEND_API void zend_objects_clone_members(zend_object *new_object, zend_object_value new_obj_val, zend_object *old_object, zend_object_handle handle TSRMLS_DC) { - zend_hash_copy(new_object->properties, old_object->properties, (copy_ctor_func_t) zval_add_ref, (void *) NULL /* Not used anymore */, sizeof(zval *)); + if (EG(ze1_compatibility_mode)) { + zend_hash_copy(new_object->properties, old_object->properties, (copy_ctor_func_t) zval_add_ref_or_clone, (void *) NULL /* Not used anymore */, sizeof(zval *)); + } else { + zend_hash_copy(new_object->properties, old_object->properties, (copy_ctor_func_t) zval_add_ref, (void *) NULL /* Not used anymore */, sizeof(zval *)); + } if (old_object->ce->clone) { zval *new_obj; zval *clone_func_name;