summaryrefslogtreecommitdiff
path: root/Zend
diff options
context:
space:
mode:
authorAndi Gutmans <andi@php.net>1999-10-28 15:53:31 +0000
committerAndi Gutmans <andi@php.net>1999-10-28 15:53:31 +0000
commit83c79bb154565843b98a0a6717559cb139b5bdd6 (patch)
tree0b3573a90a4ab0df2512d9ea0e6f31aea80bfdbb /Zend
parent10fa640f5c09c1d6ce58a8bf1b45139adf187915 (diff)
downloadphp-git-83c79bb154565843b98a0a6717559cb139b5bdd6.tar.gz
- Fix for Thies' leak and Andrei's crash
Diffstat (limited to 'Zend')
-rw-r--r--Zend/zend_compile.c1
-rw-r--r--Zend/zend_execute.c61
2 files changed, 34 insertions, 28 deletions
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 449659cf4e..0494855562 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -1957,6 +1957,7 @@ void do_foreach_end(znode *foreach_token, znode *open_brackets_token CLS_DC)
opline->opcode = ZEND_JMP;
opline->op1.u.opline_num = foreach_token->u.opline_num;
+ SET_UNUSED(opline->op1);
SET_UNUSED(opline->op2);
CG(active_op_array)->opcodes[foreach_token->u.opline_num].op2.u.opline_num = get_next_op_number(CG(active_op_array));
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index 4850126dc4..6628b13b24 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -121,7 +121,7 @@ static inline zval *_get_zval_ptr(znode *node, temp_variable *Ts, int *should_fr
T->tmp_var.value.str.val = estrndup(&c, 1);
T->tmp_var.value.str.len = 1;
}
- zval_ptr_dtor(&str);
+ PZVAL_UNLOCK(str);
T->tmp_var.refcount=1;
T->tmp_var.is_ref=1;
T->tmp_var.type = IS_STRING;
@@ -146,31 +146,34 @@ static inline zval *_get_zval_ptr(znode *node, temp_variable *Ts, int *should_fr
static inline zval *_get_object_zval_ptr(znode *node, temp_variable *Ts, int *should_free ELS_DC)
{
- switch(node->op_type) {
- case IS_TMP_VAR:
- *should_free = 1;
- return &Ts[node->u.var].tmp_var;
- break;
- case IS_VAR:
- if (Ts[node->u.var].var.ptr) {
- PZVAL_UNLOCK(Ts[node->u.var].var.ptr);
- *should_free = 0;
- return Ts[node->u.var].var.ptr;
- } else {
- *should_free = 1;
- return NULL;
- }
- break;
- case IS_UNUSED:
- return NULL;
- break;
+ switch(node->op_type) {
+ case IS_TMP_VAR:
+ *should_free = 1;
+ return &Ts[node->u.var].tmp_var;
+ break;
+ case IS_VAR:
+ if (Ts[node->u.var].var.ptr) {
+ PZVAL_UNLOCK(Ts[node->u.var].var.ptr);
+ *should_free = 0;
+ return Ts[node->u.var].var.ptr;
+ } else {
+ if (Ts[node->u.var].EA.type==IS_STRING_OFFSET) {
+ PZVAL_UNLOCK(Ts[node->u.var].EA.str);
+ }
+ *should_free = 1;
+ return NULL;
+ }
+ break;
+ case IS_UNUSED:
+ return NULL;
+ break;
#if DEBUG_ZEND
- default:
- zend_error(E_ERROR, "Unknown temporary variable type");
- break;
+ default:
+ zend_error(E_ERROR, "Unknown temporary variable type");
+ break;
#endif
- }
- return NULL;
+ }
+ return NULL;
}
@@ -180,6 +183,8 @@ static inline zval **_get_zval_ptr_ptr(znode *node, temp_variable *Ts ELS_DC)
case IS_VAR:
if (Ts[node->u.var].var.ptr_ptr) {
PZVAL_UNLOCK(*Ts[node->u.var].var.ptr_ptr);
+ } else if (Ts[node->u.var].EA.type==IS_STRING_OFFSET) {
+ PZVAL_UNLOCK(Ts[node->u.var].EA.str);
}
return Ts[node->u.var].var.ptr_ptr;
break;
@@ -689,7 +694,7 @@ static inline void zend_fetch_dimension_address(znode *result, znode *op1, znode
offset = &tmp;
}
Ts[result->u.var].EA.str = container;
- container->refcount++;
+ PZVAL_LOCK(container);
Ts[result->u.var].EA.offset = offset->value.lval;
Ts[result->u.var].EA.type = IS_STRING_OFFSET;
FREE_OP(op2, free_op2);
@@ -1404,8 +1409,8 @@ binary_assign_op_addr: {
} else { /* used for member function calls */
object.ptr = _get_object_zval_ptr(&opline->op1, Ts, &EG(free_op1) ELS_CC);
- if (!object.ptr
- || ((object.ptr->type==IS_OBJECT) && (object.ptr->value.obj.ce->handle_function_call))) { /* overloaded function call */
+ if ((!object.ptr && Ts[opline->op1.u.var].EA.type==IS_OVERLOADED_OBJECT)
+ || ((object.ptr && object.ptr->type==IS_OBJECT) && (object.ptr->value.obj.ce->handle_function_call))) { /* overloaded function call */
zend_overloaded_element overloaded_element;
zend_property_reference *property_reference;
@@ -1428,7 +1433,7 @@ binary_assign_op_addr: {
goto overloaded_function_call_cont;
}
- if (object.ptr->type != IS_OBJECT) {
+ if (!object.ptr || object.ptr->type != IS_OBJECT) {
zend_error(E_ERROR, "Call to a member function on a non-object");
}
object.ptr->refcount++; /* For this pointer */