]> granicus.if.org Git - php/commitdiff
Fixed bug #33243 (ze1_compatibility_mode does not work as expected)
authorDmitry Stogov <dmitry@php.net>
Tue, 7 Jun 2005 07:03:20 +0000 (07:03 +0000)
committerDmitry Stogov <dmitry@php.net>
Tue, 7 Jun 2005 07:03:20 +0000 (07:03 +0000)
NEWS
Zend/tests/bug33243.phpt [new file with mode: 0755]
Zend/zend_objects.c

diff --git a/NEWS b/NEWS
index 3601d9032cd947543ddb2551a590f70a519ef5d2..e74785ecbebc9a8292d1be61a931b309b51be15e 100644 (file)
--- 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 (executable)
index 0000000..bb5d77c
--- /dev/null
@@ -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--
+<?php
+$a->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)
+  }
+}
index 162905256b170830c9a92d72f0134eba1c86132a..c37b54b47a34c3afe0209e1b6c123bb7a0ef8e04 100644 (file)
@@ -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;