summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/zend_execute.c41
-rw-r--r--Zend/zend_vm_def.h19
2 files changed, 49 insertions, 11 deletions
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index 3a54926101..4dd96fce14 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -530,15 +530,19 @@ static inline void zend_assign_to_object(znode *result, zval **object_ptr, znode
/* separate our value if necessary */
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", Z_OBJCE_P(orig_value)->name);
+ 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'", Z_OBJCE_P(orig_value)->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);
} else if (value_op->op_type == IS_TMP_VAR) {
zval *orig_value = value;
@@ -547,6 +551,9 @@ static inline void zend_assign_to_object(znode *result, zval **object_ptr, znode
*value = *orig_value;
value->is_ref = 0;
value->refcount = 0;
+ if(dup) {
+ efree(class_name);
+ }
} else if (value_op->op_type == IS_CONST) {
zval *orig_value = value;
@@ -684,8 +691,14 @@ static inline void zend_assign_to_variable(znode *result, znode *op1, znode *op2
}
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", Z_OBJCE_P(value)->name);
+ 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;
@@ -698,7 +711,7 @@ static inline void zend_assign_to_variable(znode *result, znode *op1, znode *op2
*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'", Z_OBJCE_P(value)->name);
+ 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--;
@@ -717,11 +730,14 @@ static inline void zend_assign_to_variable(znode *result, znode *op1, znode *op2
}
*variable_ptr = *value;
INIT_PZVAL(variable_ptr);
- zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", Z_OBJCE_P(value)->name);
+ 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;
@@ -815,17 +831,26 @@ static inline void zend_receive(zval **variable_ptr_ptr, zval *value TSRMLS_DC)
zval *variable_ptr = *variable_ptr_ptr;
if (EG(ze1_compatibility_mode) && Z_TYPE_P(value) == IS_OBJECT) {
- if (Z_OBJ_HANDLER_P(value, clone_obj) == NULL) {
- zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %s", Z_OBJCE_P(value)->name);
+ 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'", Z_OBJCE_P(value)->name);
+ 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;
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 3042409f5f..3fd6ae6bfb 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -2014,15 +2014,22 @@ ZEND_VM_C_LABEL(return_by_value):
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(orig_value, &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", Z_OBJCE_P(retval_ptr)->name);
+ 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'", Z_OBJCE_P(retval_ptr)->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)) {
@@ -2948,6 +2955,12 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY)
if (array_ptr_ptr == NULL) {
ALLOC_INIT_ZVAL(array_ptr);
} else if (Z_TYPE_PP(array_ptr_ptr) == IS_OBJECT) {
+ if(Z_OBJ_HT_PP(array_ptr_ptr)->get_class_entry == NULL) {
+ zend_error(E_WARNING, "foreach() can not iterate over objects without PHP class");
+ ZEND_VM_SET_OPCODE(EX(op_array)->opcodes+opline->op2.u.opline_num);
+ ZEND_VM_CONTINUE_JMP();
+ }
+
ce = Z_OBJCE_PP(array_ptr_ptr);
if (!ce || ce->get_iterator == NULL) {
SEPARATE_ZVAL_IF_NOT_REF(array_ptr_ptr);
@@ -3509,7 +3522,7 @@ ZEND_VM_HANDLER(138, ZEND_INSTANCEOF, TMP|VAR|CV, ANY)
zval *expr = GET_OP1_ZVAL_PTR(BP_VAR_R);
zend_bool result;
- if (Z_TYPE_P(expr) == IS_OBJECT) {
+ if (Z_TYPE_P(expr) == IS_OBJECT && Z_OBJ_HT_P(expr)->get_class_entry) {
result = instanceof_function(Z_OBJCE_P(expr), EX_T(opline->op2.u.var).class_entry TSRMLS_CC);
} else {
result = 0;