summaryrefslogtreecommitdiff
path: root/Zend/zend_execute.c
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@php.net>2005-06-03 11:16:19 +0000
committerDmitry Stogov <dmitry@php.net>2005-06-03 11:16:19 +0000
commit3d7b0bab28e74aa618a68c35e3ff0a5718fc337e (patch)
tree6b49bffc1a4f740a7391dad15033e545d6f1724b /Zend/zend_execute.c
parentd486da963e02271623db034adde6fc55d9fcb6cb (diff)
downloadphp-git-3d7b0bab28e74aa618a68c35e3ff0a5718fc337e.tar.gz
Fixed memory allocation bugs related to magic object handlers (__get(), __set(),
...)
Diffstat (limited to 'Zend/zend_execute.c')
-rw-r--r--Zend/zend_execute.c84
1 files changed, 34 insertions, 50 deletions
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index 35798a4182..0a69d16747 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -139,6 +139,17 @@ static inline void zend_pzval_unlock_free_func(zval *z)
(z)->refcount = 1; \
(z)->is_ref = 0;
+#define MAKE_REAL_ZVAL_PTR(val) \
+ do { \
+ zval *_tmp; \
+ ALLOC_ZVAL(_tmp); \
+ _tmp->value = (val)->value; \
+ _tmp->type = (val)->type; \
+ _tmp->refcount = 1; \
+ _tmp->is_ref = 0; \
+ val = _tmp; \
+ } while (0)
+
/* End of zend_execute_locks.h */
#define CV_OF(i) (EG(current_execute_data)->CVs[i])
@@ -679,41 +690,31 @@ static inline void zend_assign_to_object(znode *result, zval **object_ptr, znode
value->refcount++;
if (opcode == ZEND_ASSIGN_OBJ) {
- zval tmp;
-
- switch (op2->op_type) {
- case IS_CONST:
- /* already a constant string */
- break;
- case IS_CV:
- case IS_VAR:
- tmp = *property_name;
- zval_copy_ctor(&tmp);
- convert_to_string(&tmp);
- property_name = &tmp;
- break;
- case IS_TMP_VAR:
- convert_to_string(property_name);
- break;
+ if (IS_TMP_FREE(free_op2)) {
+ MAKE_REAL_ZVAL_PTR(property_name);
}
Z_OBJ_HT_P(object)->write_property(object, property_name, value TSRMLS_CC);
- if (property_name == &tmp) {
- zval_dtor(property_name);
- }
} else {
/* Note: property_name in this case is really the array index! */
if (!Z_OBJ_HT_P(object)->write_dimension) {
zend_error_noreturn(E_ERROR, "Cannot use object as array");
}
+ if (IS_TMP_FREE(free_op2)) {
+ MAKE_REAL_ZVAL_PTR(property_name);
+ }
Z_OBJ_HT_P(object)->write_dimension(object, property_name, value TSRMLS_CC);
}
- FREE_OP(free_op2);
if (result && !RETURN_VALUE_UNUSED(result)) {
T(result->u.var).var.ptr = value;
T(result->u.var).var.ptr_ptr = &T(result->u.var).var.ptr; /* this is so that we could use it in FETCH_DIM_R, etc. - see bug #27876 */
PZVAL_LOCK(value);
}
+ if (IS_TMP_FREE(free_op2)) {
+ zval_ptr_dtor(&property_name);
+ } else {
+ FREE_OP(free_op2);
+ }
zval_ptr_dtor(&value);
FREE_OP_IF_VAR(free_value);
}
@@ -1100,7 +1101,7 @@ fetch_string_dim:
return retval;
}
-static void zend_fetch_dimension_address(temp_variable *result, zval **container_ptr, zval *dim, int type TSRMLS_DC)
+static void zend_fetch_dimension_address(temp_variable *result, zval **container_ptr, zval *dim, int dim_is_tmp_var, int type TSRMLS_DC)
{
zval *container;
@@ -1145,9 +1146,6 @@ static void zend_fetch_dimension_address(temp_variable *result, zval **container
container = *container_ptr;
}
if (dim == NULL) {
-/*
- if (op2->op_type == IS_UNUSED) {
-*/
zval *new_zval = &EG(uninitialized_zval);
new_zval->refcount++;
@@ -1179,9 +1177,6 @@ static void zend_fetch_dimension_address(temp_variable *result, zval **container
zval tmp;
if (dim == NULL) {
-/*
- if (op2->op_type==IS_UNUSED) {
-*/
zend_error_noreturn(E_ERROR, "[] operator not supported for strings");
}
@@ -1218,7 +1213,14 @@ static void zend_fetch_dimension_address(temp_variable *result, zval **container
if (!Z_OBJ_HT_P(container)->read_dimension) {
zend_error_noreturn(E_ERROR, "Cannot use object as array");
} else {
- zval *overloaded_result = Z_OBJ_HT_P(container)->read_dimension(container, dim, type TSRMLS_CC);
+ zval *overloaded_result;
+
+ if (dim_is_tmp_var) {
+ zval *orig = dim;
+ MAKE_REAL_ZVAL_PTR(dim);
+ ZVAL_NULL(orig);
+ }
+ overloaded_result = Z_OBJ_HT_P(container)->read_dimension(container, dim, type TSRMLS_CC);
if (overloaded_result) {
switch (type) {
@@ -1240,6 +1242,9 @@ static void zend_fetch_dimension_address(temp_variable *result, zval **container
AI_USE_PTR(result->var);
PZVAL_LOCK(*result->var.ptr_ptr);
}
+ if (dim_is_tmp_var) {
+ zval_ptr_dtor(&dim);
+ }
return;
}
break;
@@ -1271,10 +1276,9 @@ static void zend_fetch_dimension_address(temp_variable *result, zval **container
}
}
-static void zend_fetch_property_address(temp_variable *result, zval **container_ptr, zval *prop_ptr, int op2_type, int type TSRMLS_DC)
+static void zend_fetch_property_address(temp_variable *result, zval **container_ptr, zval *prop_ptr, int type TSRMLS_DC)
{
zval *container;
- zval tmp;
container = *container_ptr;
if (container == EG(error_zval_ptr)) {
@@ -1317,22 +1321,6 @@ static void zend_fetch_property_address(temp_variable *result, zval **container_
container = *container_ptr;
}
- switch (op2_type) {
- case IS_CONST:
- /* already a constant string */
- break;
- case IS_CV:
- case IS_VAR:
- tmp = *prop_ptr;
- zval_copy_ctor(&tmp);
- convert_to_string(&tmp);
- prop_ptr = &tmp;
- break;
- case IS_TMP_VAR:
- convert_to_string(prop_ptr);
- break;
- }
-
if (Z_OBJ_HT_P(container)->get_property_ptr_ptr) {
zval **ptr_ptr = Z_OBJ_HT_P(container)->get_property_ptr_ptr(container, prop_ptr TSRMLS_CC);
if(NULL == ptr_ptr) {
@@ -1362,10 +1350,6 @@ static void zend_fetch_property_address(temp_variable *result, zval **container_
}
}
- if (prop_ptr == &tmp) {
- zval_dtor(prop_ptr);
- }
-
if (result) {
PZVAL_LOCK(*result->var.ptr_ptr);
}