diff options
Diffstat (limited to 'Zend/zend_vm_execute.h')
-rw-r--r-- | Zend/zend_vm_execute.h | 80 |
1 files changed, 76 insertions, 4 deletions
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; |