summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/tests/bug30332.phpt40
-rw-r--r--Zend/tests/bug31828.phpt25
-rw-r--r--Zend/tests/bug32080.phpt18
-rw-r--r--Zend/tests/bug32852.phpt38
-rwxr-xr-xZend/tests/bug33243.phpt25
-rwxr-xr-xZend/tests/bug34712.phpt28
-rwxr-xr-xZend/tests/bug34767.phpt33
-rw-r--r--Zend/zend.c1
-rw-r--r--Zend/zend_API.c19
-rw-r--r--Zend/zend_execute.c104
-rw-r--r--Zend/zend_execute.h9
-rw-r--r--Zend/zend_execute_API.c7
-rw-r--r--Zend/zend_globals.h1
-rw-r--r--Zend/zend_objects.c7
-rw-r--r--Zend/zend_operators.c36
-rw-r--r--Zend/zend_vm_def.h20
-rw-r--r--Zend/zend_vm_execute.h80
17 files changed, 474 insertions, 17 deletions
diff --git a/Zend/tests/bug30332.phpt b/Zend/tests/bug30332.phpt
new file mode 100644
index 0000000000..e2478498cd
--- /dev/null
+++ b/Zend/tests/bug30332.phpt
@@ -0,0 +1,40 @@
+--TEST--
+Bug #30332 (zend.ze1_compatibility_mode isnt fully compatable with array_push())
+--INI--
+zend.ze1_compatibility_mode=on
+error_reporting=4095
+--FILE--
+<?php
+class x { };
+
+$first = new x;
+$second = $first;
+$container = array();
+array_push($container, $first);
+
+$first->first = " im in the first";
+
+print_r($first);
+print_r($second);
+print_r($container);
+?>
+--EXPECTF--
+Strict Standards: Implicit cloning object of class 'x' because of 'zend.ze1_compatibility_mode' in %sbug30332.php on line 4
+
+Strict Standards: Implicit cloning object of class 'x' because of 'zend.ze1_compatibility_mode' in %sbug30332.php on line 5
+
+Strict Standards: Implicit cloning object of class 'x' because of 'zend.ze1_compatibility_mode' in %sbug30332.php on line 7
+x Object
+(
+ [first] => im in the first
+)
+x Object
+(
+)
+Array
+(
+ [0] => x Object
+ (
+ )
+
+)
diff --git a/Zend/tests/bug31828.phpt b/Zend/tests/bug31828.phpt
new file mode 100644
index 0000000000..a3cc4542fd
--- /dev/null
+++ b/Zend/tests/bug31828.phpt
@@ -0,0 +1,25 @@
+--TEST--
+Bug #31828 (Crash with zend.ze1_compatibility_mode=On)
+--INI--
+zend.ze1_compatibility_mode=on
+error_reporting=4095
+--FILE--
+<?php
+$o = new stdClass();
+$o->id = 77;
+$o->name = "Aerospace";
+$a[] = $o;
+$a = $a[0];
+print_r($a);
+?>
+--EXPECTF--
+Strict Standards: Implicit cloning object of class 'stdClass' because of 'zend.ze1_compatibility_mode' in %sbug31828.php on line 2
+
+Strict Standards: Implicit cloning object of class 'stdClass' because of 'zend.ze1_compatibility_mode' in %sbug31828.php on line 5
+
+Strict Standards: Implicit cloning object of class 'stdClass' because of 'zend.ze1_compatibility_mode' in %sbug31828.php on line 6
+stdClass Object
+(
+ [id] => 77
+ [name] => Aerospace
+)
diff --git a/Zend/tests/bug32080.phpt b/Zend/tests/bug32080.phpt
new file mode 100644
index 0000000000..a96c8bf262
--- /dev/null
+++ b/Zend/tests/bug32080.phpt
@@ -0,0 +1,18 @@
+--TEST--
+Bug #32080 (segfault when assigning object to itself with zend.ze1_compatibility_mode=On)
+--INI--
+zend.ze1_compatibility_mode=on
+error_reporting=4095
+--FILE--
+<?php
+class test { }
+$t = new test;
+$t = $t; // gives segfault
+var_dump($t);
+?>
+--EXPECTF--
+Strict Standards: Implicit cloning object of class 'test' because of 'zend.ze1_compatibility_mode' in %sbug32080.php on line 3
+
+Strict Standards: Implicit cloning object of class 'test' because of 'zend.ze1_compatibility_mode' in %sbug32080.php on line 5
+object(test)#%d (0) {
+}
diff --git a/Zend/tests/bug32852.phpt b/Zend/tests/bug32852.phpt
new file mode 100644
index 0000000000..38cea6f145
--- /dev/null
+++ b/Zend/tests/bug32852.phpt
@@ -0,0 +1,38 @@
+--TEST--
+Bug #32852 (Crash with singleton and __destruct when zend.ze1_compatibility_mode = On)
+--INI--
+zend.ze1_compatibility_mode=on
+error_reporting=4095
+--FILE--
+<?php
+class crashme {
+ private static $instance = null;
+
+ public function __construct() {
+ self::$instance = $this;
+ }
+
+ public function __destruct() {
+ echo "i'm called\n";
+ }
+
+ public static function singleton() {
+ if (!isset(self::$instance)) {
+ self::$instance = new crashme();
+ }
+ return self::$instance;
+ }
+}
+
+crashme::singleton();
+?>
+--EXPECTF--
+Strict Standards: Implicit cloning object of class 'crashme' because of 'zend.ze1_compatibility_mode' in %sbug32852.php on line 6
+i'm called
+
+Strict Standards: Implicit cloning object of class 'crashme' because of 'zend.ze1_compatibility_mode' in %sbug32852.php on line 15
+i'm called
+
+Strict Standards: Implicit cloning object of class 'crashme' because of 'zend.ze1_compatibility_mode' in %sbug32852.php on line 17
+i'm called
+i'm called
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--
+<?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)
+ }
+}
diff --git a/Zend/tests/bug34712.phpt b/Zend/tests/bug34712.phpt
new file mode 100755
index 0000000000..db7860cd38
--- /dev/null
+++ b/Zend/tests/bug34712.phpt
@@ -0,0 +1,28 @@
+--TEST--
+Bug #34712 zend.ze1_compatibility_mode = on segfault
+--INI--
+zend.ze1_compatibility_mode=1
+error_reporting=4095
+--FILE--
+<?php
+class foo {
+ function foo(&$obj_ref) {
+ $this->bar = &$obj_ref;
+ }
+}
+
+
+class bar {
+ function bar() {
+ $this->foo = new foo($this);
+ }
+}
+
+$test = new bar;
+echo "ok\n";
+?>
+--EXPECTF--
+Strict Standards: Implicit cloning object of class 'foo' because of 'zend.ze1_compatibility_mode' in %sbug34712.php on line 11
+
+Strict Standards: Implicit cloning object of class 'bar' because of 'zend.ze1_compatibility_mode' in %sbug34712.php on line 15
+ok
diff --git a/Zend/tests/bug34767.phpt b/Zend/tests/bug34767.phpt
new file mode 100755
index 0000000000..45af9f944c
--- /dev/null
+++ b/Zend/tests/bug34767.phpt
@@ -0,0 +1,33 @@
+--TEST--
+Bug #34767 (Zend Engine 1 Compatibility not copying objects correctly)
+--INI--
+zend.ze1_compatibility_mode=1
+error_reporting=4095
+--FILE--
+<?php
+$a->y = &new stdClass();
+print_r($a);
+$b = $a;
+$a->y->z = 1;
+print_r($b);
+?>
+--EXPECTF--
+
+Strict Standards: Assigning the return value of new by reference is deprecated in %sbug34767.php on line 2
+stdClass Object
+(
+ [y] => stdClass Object
+ (
+ )
+
+)
+
+Strict Standards: Implicit cloning object of class 'stdClass' because of 'zend.ze1_compatibility_mode' in %sbug34767.php on line 4
+stdClass Object
+(
+ [y] => stdClass Object
+ (
+ [z] => 1
+ )
+
+)
diff --git a/Zend/zend.c b/Zend/zend.c
index d63ec97198..e12598e63d 100644
--- a/Zend/zend.c
+++ b/Zend/zend.c
@@ -77,6 +77,7 @@ static ZEND_INI_MH(OnUpdateErrorReporting)
ZEND_INI_BEGIN()
ZEND_INI_ENTRY("error_reporting", NULL, ZEND_INI_ALL, OnUpdateErrorReporting)
+ STD_ZEND_INI_BOOLEAN("zend.ze1_compatibility_mode", "0", ZEND_INI_ALL, OnUpdateBool, ze1_compatibility_mode, zend_executor_globals, executor_globals)
#ifdef ZEND_MULTIBYTE
STD_ZEND_INI_BOOLEAN("detect_unicode", "1", ZEND_INI_ALL, OnUpdateBool, detect_unicode, zend_compiler_globals, compiler_globals)
#endif
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index b87da8884e..b32b9eb47d 100644
--- a/Zend/zend_API.c
+++ b/Zend/zend_API.c
@@ -154,6 +154,25 @@ ZEND_API int _zend_get_parameters_array_ex(int param_count, zval ***argument_arr
while (param_count-->0) {
zval **value = (zval**)(p-arg_count);
+ if (EG(ze1_compatibility_mode) && Z_TYPE_PP(value) == IS_OBJECT) {
+ zval *value_ptr;
+ char *class_name;
+ zend_uint class_name_len;
+ int dup;
+
+ dup = zend_get_object_classname(*value, &class_name, &class_name_len TSRMLS_CC);
+
+ ALLOC_ZVAL(value_ptr);
+ *value_ptr = **value;
+ INIT_PZVAL(value_ptr);
+ zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name);
+ if(!dup) {
+ efree(class_name);
+ }
+ value_ptr->value.obj = Z_OBJ_HANDLER_PP(value, clone_obj)(*value TSRMLS_CC);
+ zval_ptr_dtor(value);
+ *value = value_ptr;
+ }
*(argument_array++) = value;
arg_count--;
}
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index f7a19a5845..99fb7ac7ad 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -554,11 +554,30 @@ static inline void zend_assign_to_object(znode *result, zval **object_ptr, znode
FREE_OP(free_value);
return;
}
-
+
/* here we are sure we are dealing with an object */
/* separate our value if necessary */
- if (value_op->op_type == IS_TMP_VAR) {
+ if (EG(ze1_compatibility_mode) && Z_TYPE_P(value) == IS_OBJECT) {
+ zval *orig_value = value;
+ char *class_name;
+ zend_uint class_name_len;
+ int dup;
+
+ ALLOC_ZVAL(value);
+ *value = *orig_value;
+ value->is_ref = 0;
+ value->refcount = 0;
+ dup = zend_get_object_classname(orig_value, &class_name, &class_name_len TSRMLS_CC);
+ if (Z_OBJ_HANDLER_P(value, clone_obj) == NULL) {
+ zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %s", class_name);
+ }
+ zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name);
+ value->value.obj = Z_OBJ_HANDLER_P(orig_value, clone_obj)(orig_value TSRMLS_CC);
+ if(!dup) {
+ efree(class_name);
+ }
+ } else if (value_op->op_type == IS_TMP_VAR) {
zval *orig_value = value;
ALLOC_ZVAL(value);
@@ -701,7 +720,55 @@ static inline void zend_assign_to_variable(znode *result, znode *op1, znode *op2
goto done_setting_var;
}
- if (PZVAL_IS_REF(variable_ptr)) {
+ if (EG(ze1_compatibility_mode) && Z_TYPE_P(value) == IS_OBJECT) {
+ char *class_name;
+ zend_uint class_name_len;
+ int dup;
+
+ dup = zend_get_object_classname(value, &class_name, &class_name_len TSRMLS_CC);
+
+ if (Z_OBJ_HANDLER_P(value, clone_obj) == NULL) {
+ zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %s", class_name);
+ } else if (PZVAL_IS_REF(variable_ptr)) {
+ if (variable_ptr != value) {
+ zend_uint refcount = variable_ptr->refcount;
+ zval garbage;
+
+ if (type != IS_TMP_VAR) {
+ value->refcount++;
+ }
+ garbage = *variable_ptr;
+ *variable_ptr = *value;
+ variable_ptr->refcount = refcount;
+ variable_ptr->is_ref = 1;
+ zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name);
+ variable_ptr->value.obj = Z_OBJ_HANDLER_P(value, clone_obj)(value TSRMLS_CC);
+ if (type != IS_TMP_VAR) {
+ value->refcount--;
+ }
+ zendi_zval_dtor(garbage);
+ }
+ } else {
+ if (variable_ptr != value) {
+ value->refcount++;
+ variable_ptr->refcount--;
+ if (variable_ptr->refcount == 0) {
+ zendi_zval_dtor(*variable_ptr);
+ } else {
+ ALLOC_ZVAL(variable_ptr);
+ *variable_ptr_ptr = variable_ptr;
+ }
+ *variable_ptr = *value;
+ INIT_PZVAL(variable_ptr);
+ zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name);
+ variable_ptr->value.obj = Z_OBJ_HANDLER_P(value, clone_obj)(value TSRMLS_CC);
+ zval_ptr_dtor(&value);
+ }
+ }
+ if (!dup) {
+ efree(class_name);
+ }
+ } else if (PZVAL_IS_REF(variable_ptr)) {
if (variable_ptr!=value) {
zend_uint refcount = variable_ptr->refcount;
zval garbage;
@@ -791,9 +858,34 @@ done_setting_var:
static inline void zend_receive(zval **variable_ptr_ptr, zval *value TSRMLS_DC)
{
- (*variable_ptr_ptr)->refcount--;
- *variable_ptr_ptr = value;
- value->refcount++;
+ zval *variable_ptr = *variable_ptr_ptr;
+
+ if (EG(ze1_compatibility_mode) && Z_TYPE_P(value) == IS_OBJECT) {
+ char *class_name;
+ zend_uint class_name_len;
+ int dup;
+
+ dup = zend_get_object_classname(value, &class_name, &class_name_len TSRMLS_CC);
+
+ if (Z_OBJ_HANDLER_P(value, clone_obj) == NULL) {
+ zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %s", class_name);
+ } else {
+ variable_ptr->refcount--;
+ ALLOC_ZVAL(variable_ptr);
+ *variable_ptr_ptr = variable_ptr;
+ *variable_ptr = *value;
+ INIT_PZVAL(variable_ptr);
+ zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name);
+ variable_ptr->value.obj = Z_OBJ_HANDLER_P(value, clone_obj)(value TSRMLS_CC);
+ }
+ if (!dup) {
+ efree(class_name);
+ }
+ } else {
+ variable_ptr->refcount--;
+ *variable_ptr_ptr = value;
+ value->refcount++;
+ }
}
/* Utility Functions for Extensions */
diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h
index a76c688513..11b92bd680 100644
--- a/Zend/zend_execute.h
+++ b/Zend/zend_execute.h
@@ -116,8 +116,15 @@ static inline int i_zend_is_true(zval *op)
break;
}
}
+
+ if(EG(ze1_compatibility_mode)) {
+ result = (zend_hash_num_elements(Z_OBJPROP_P(op))?1:0);
+ } else {
+ result = 1;
+ }
+ } else {
+ result = 1;
}
- result = 1;
break;
default:
result = 0;
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
index 7b9f141775..e7d78c4029 100644
--- a/Zend/zend_execute_API.c
+++ b/Zend/zend_execute_API.c
@@ -395,6 +395,13 @@ ZEND_API void _zval_ptr_dtor(zval **zval_ptr ZEND_FILE_LINE_DC)
zval_dtor(*zval_ptr);
safe_free_zval_ptr_rel(*zval_ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC);
} else if ((*zval_ptr)->refcount == 1) {
+ if ((*zval_ptr)->type == IS_OBJECT) {
+ TSRMLS_FETCH();
+
+ if (EG(ze1_compatibility_mode)) {
+ return;
+ }
+ }
(*zval_ptr)->is_ref = 0;
}
}
diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h
index d1bda5b064..72d045e281 100644
--- a/Zend/zend_globals.h
+++ b/Zend/zend_globals.h
@@ -200,6 +200,7 @@ struct _zend_executor_globals {
HashTable *in_autoload;
zend_function *autoload_func;
zend_bool full_tables_cleanup;
+ zend_bool ze1_compatibility_mode;
/* for extended information support */
zend_bool no_extensions;
diff --git a/Zend/zend_objects.c b/Zend/zend_objects.c
index e2d86e8fe8..6dc4ba4aa3 100644
--- a/Zend/zend_objects.c
+++ b/Zend/zend_objects.c
@@ -158,8 +158,11 @@ static void zval_add_ref_or_clone(zval **p)
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;
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c
index 65a224840a..37f412fe75 100644
--- a/Zend/zend_operators.c
+++ b/Zend/zend_operators.c
@@ -340,7 +340,14 @@ ZEND_API void convert_to_long_base(zval *op, int base)
return;
}
- zend_error(E_NOTICE, "Object of class %s could not be converted to int", Z_OBJCE_P(op)->name);
+ if (EG(ze1_compatibility_mode)) {
+ HashTable *ht = Z_OBJPROP_P(op);
+ if (ht) {
+ retval = (zend_hash_num_elements(ht)?1:0);
+ }
+ } else {
+ zend_error(E_NOTICE, "Object of class %s could not be converted to int", Z_OBJCE_P(op)->name);
+ }
zval_dtor(op);
ZVAL_LONG(op, retval);
return;
@@ -399,7 +406,15 @@ ZEND_API void convert_to_double(zval *op)
return;
}
- zend_error(E_NOTICE, "Object of class %s could not be converted to double", Z_OBJCE_P(op)->name);
+ if (EG(ze1_compatibility_mode)) {
+ HashTable *ht = Z_OBJPROP_P(op);
+ if (ht) {
+ retval = (zend_hash_num_elements(ht)?1.0:0.0);
+ }
+ } else {
+ zend_error(E_NOTICE, "Object of class %s could not be converted to double", Z_OBJCE_P(op)->name);
+ }
+
zval_dtor(op);
ZVAL_DOUBLE(op, retval);
break;
@@ -486,6 +501,13 @@ ZEND_API void convert_to_boolean(zval *op)
return;
}
+ if (EG(ze1_compatibility_mode)) {
+ HashTable *ht = Z_OBJPROP_P(op);
+ if (ht) {
+ retval = (zend_hash_num_elements(ht)?1:0);
+ }
+ }
+
zval_dtor(op);
ZVAL_BOOL(op, retval);
break;
@@ -1452,7 +1474,15 @@ ZEND_API int is_identical_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
break;
case IS_OBJECT:
if (Z_OBJ_HT_P(op1) == Z_OBJ_HT_P(op2)) {
- result->value.lval = (Z_OBJ_HANDLE_P(op1) == Z_OBJ_HANDLE_P(op2));
+ if (EG(ze1_compatibility_mode)) {
+ zend_compare_objects(result, op1, op2 TSRMLS_CC);
+ /* comparison returns 0 in case of equality and
+ * 1 in case of ineqaulity, we need to reverse it
+ */
+ result->value.lval = !result->value.lval;
+ } else {
+ result->value.lval = (Z_OBJ_HANDLE_P(op1) == Z_OBJ_HANDLE_P(op2));
+ }
} else {
result->value.lval = 0;
}
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index b69a7a6017..5295320de9 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -2047,7 +2047,25 @@ ZEND_VM_C_LABEL(return_by_value):
retval_ptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
- if (!IS_OP1_TMP_FREE()) { /* Not a temp var */
+ if (EG(ze1_compatibility_mode) && Z_TYPE_P(retval_ptr) == IS_OBJECT) {
+ zval *ret;
+ char *class_name;
+ zend_uint class_name_len;
+ int dup;
+
+ ALLOC_ZVAL(ret);
+ INIT_PZVAL_COPY(ret, retval_ptr);
+ dup = zend_get_object_classname(retval_ptr, &class_name, &class_name_len TSRMLS_CC);
+ if (Z_OBJ_HT_P(retval_ptr)->clone_obj == NULL) {
+ zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %s", class_name);
+ }
+ zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name);
+ ret->value.obj = Z_OBJ_HT_P(retval_ptr)->clone_obj(retval_ptr TSRMLS_CC);
+ *EG(return_value_ptr_ptr) = ret;
+ if (!dup) {
+ efree(class_name);
+ }
+ } else if (!IS_OP1_TMP_FREE()) { /* Not a temp var */
if (EG(active_op_array)->return_reference == ZEND_RETURN_REF ||
(PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0)) {
zval *ret;
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 0300a92c45..8dc247d4fd 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -1686,7 +1686,25 @@ return_by_value:
retval_ptr = &opline->op1.u.constant;
- if (!0) { /* Not a temp var */
+ if (EG(ze1_compatibility_mode) && Z_TYPE_P(retval_ptr) == IS_OBJECT) {
+ zval *ret;
+ char *class_name;
+ zend_uint class_name_len;
+ int dup;
+
+ ALLOC_ZVAL(ret);
+ INIT_PZVAL_COPY(ret, retval_ptr);
+ dup = zend_get_object_classname(retval_ptr, &class_name, &class_name_len TSRMLS_CC);
+ if (Z_OBJ_HT_P(retval_ptr)->clone_obj == NULL) {
+ zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %s", class_name);
+ }
+ zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name);
+ ret->value.obj = Z_OBJ_HT_P(retval_ptr)->clone_obj(retval_ptr TSRMLS_CC);
+ *EG(return_value_ptr_ptr) = ret;
+ if (!dup) {
+ efree(class_name);
+ }
+ } else if (!0) { /* Not a temp var */
if (EG(active_op_array)->return_reference == ZEND_RETURN_REF ||
(PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0)) {
zval *ret;
@@ -4115,7 +4133,25 @@ return_by_value:
retval_ptr = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
- if (!1) { /* Not a temp var */
+ if (EG(ze1_compatibility_mode) && Z_TYPE_P(retval_ptr) == IS_OBJECT) {
+ zval *ret;
+ char *class_name;
+ zend_uint class_name_len;
+ int dup;
+
+ ALLOC_ZVAL(ret);
+ INIT_PZVAL_COPY(ret, retval_ptr);
+ dup = zend_get_object_classname(retval_ptr, &class_name, &class_name_len TSRMLS_CC);
+ if (Z_OBJ_HT_P(retval_ptr)->clone_obj == NULL) {
+ zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %s", class_name);
+ }
+ zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name);
+ ret->value.obj = Z_OBJ_HT_P(retval_ptr)->clone_obj(retval_ptr TSRMLS_CC);
+ *EG(return_value_ptr_ptr) = ret;
+ if (!dup) {
+ efree(class_name);
+ }
+ } else if (!1) { /* Not a temp var */
if (EG(active_op_array)->return_reference == ZEND_RETURN_REF ||
(PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0)) {
zval *ret;
@@ -7036,7 +7072,25 @@ return_by_value:
retval_ptr = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
- if (!0) { /* Not a temp var */
+ if (EG(ze1_compatibility_mode) && Z_TYPE_P(retval_ptr) == IS_OBJECT) {
+ zval *ret;
+ char *class_name;
+ zend_uint class_name_len;
+ int dup;
+
+ ALLOC_ZVAL(ret);
+ INIT_PZVAL_COPY(ret, retval_ptr);
+ dup = zend_get_object_classname(retval_ptr, &class_name, &class_name_len TSRMLS_CC);
+ if (Z_OBJ_HT_P(retval_ptr)->clone_obj == NULL) {
+ zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %s", class_name);
+ }
+ zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name);
+ ret->value.obj = Z_OBJ_HT_P(retval_ptr)->clone_obj(retval_ptr TSRMLS_CC);
+ *EG(return_value_ptr_ptr) = ret;
+ if (!dup) {
+ efree(class_name);
+ }
+ } else if (!0) { /* Not a temp var */
if (EG(active_op_array)->return_reference == ZEND_RETURN_REF ||
(PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0)) {
zval *ret;
@@ -19156,7 +19210,25 @@ return_by_value:
retval_ptr = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
- if (!0) { /* Not a temp var */
+ if (EG(ze1_compatibility_mode) && Z_TYPE_P(retval_ptr) == IS_OBJECT) {
+ zval *ret;
+ char *class_name;
+ zend_uint class_name_len;
+ int dup;
+
+ ALLOC_ZVAL(ret);
+ INIT_PZVAL_COPY(ret, retval_ptr);
+ dup = zend_get_object_classname(retval_ptr, &class_name, &class_name_len TSRMLS_CC);
+ if (Z_OBJ_HT_P(retval_ptr)->clone_obj == NULL) {
+ zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %s", class_name);
+ }
+ zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name);
+ ret->value.obj = Z_OBJ_HT_P(retval_ptr)->clone_obj(retval_ptr TSRMLS_CC);
+ *EG(return_value_ptr_ptr) = ret;
+ if (!dup) {
+ efree(class_name);
+ }
+ } else if (!0) { /* Not a temp var */
if (EG(active_op_array)->return_reference == ZEND_RETURN_REF ||
(PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0)) {
zval *ret;