diff options
Diffstat (limited to 'Zend/zend_objects.c')
| -rw-r--r-- | Zend/zend_objects.c | 58 | 
1 files changed, 31 insertions, 27 deletions
| diff --git a/Zend/zend_objects.c b/Zend/zend_objects.c index 4d3398dc37..d1074dd237 100644 --- a/Zend/zend_objects.c +++ b/Zend/zend_objects.c @@ -24,7 +24,14 @@  #include "zend_variables.h"  #include "zend_API.h" -static inline void zend_objects_call_destructor(zend_object *object, zend_object_handle handle TSRMLS_DC) +static inline void zend_nuke_object(zend_object *object TSRMLS_DC) +{ +	zend_hash_destroy(object->properties); +	FREE_HASHTABLE(object->properties); +	efree(object); +} + +ZEND_API void zend_objects_destroy_object(zend_object *object, zend_object_handle handle TSRMLS_DC)  {  	zend_function *destructor = object->ce->destructor; @@ -34,34 +41,40 @@ static inline void zend_objects_call_destructor(zend_object *object, zend_object  		zval *retval_ptr;  		HashTable symbol_table; +		if (destructor->op_array.fn_flags & (ZEND_ACC_PRIVATE|ZEND_ACC_PROTECTED)) { +			if (destructor->op_array.fn_flags & ZEND_ACC_PRIVATE) { +				/* Ensure that if we're calling a private function, we're allowed to do so. +				 */ +				if (object->ce != EG(scope)) { +					zend_nuke_object(object TSRMLS_CC); /* unfortunately we *must* destroy it now anyway */ +					zend_error(E_ERROR, "Call to private destructor from context '%s'", EG(scope) ? EG(scope)->name : ""); +					return; +				} +			} else { +				/* Ensure that if we're calling a protected function, we're allowed to do so. +				 */ +				if (!zend_check_protected(destructor->common.scope, EG(scope))) { +					zend_nuke_object(object TSRMLS_CC); /* unfortunately we *must* destroy it now anyway */ +					zend_error(E_ERROR, "Call to protected destructor from context '%s'", EG(scope) ? EG(scope)->name : ""); +					return; +				} +			} +		} +  		MAKE_STD_ZVAL(obj);  		obj->type = IS_OBJECT;  		obj->value.obj.handle = handle;  		obj->value.obj.handlers = &std_object_handlers;  		zval_copy_ctor(obj); +		ZEND_INIT_SYMTABLE(&symbol_table); +		  		/* FIXME: Optimize this so that we use the old_object->ce->destructor function pointer instead of the name */  		MAKE_STD_ZVAL(destructor_func_name);  		destructor_func_name->type = IS_STRING;  		destructor_func_name->value.str.val = estrndup("__destruct", sizeof("__destruct")-1);  		destructor_func_name->value.str.len = sizeof("__destruct")-1; -		if (destructor->op_array.fn_flags & ZEND_ACC_PRIVATE) { -			/* Ensure that if we're calling a private function, we're allowed to do so. -			 */ -			if (object->ce != EG(scope)) { -				zend_error(E_ERROR, "Call to private destructor from context '%s'", EG(scope) ? EG(scope)->name : ""); -			} -		} else if ((destructor->common.fn_flags & ZEND_ACC_PROTECTED)) { -			/* Ensure that if we're calling a protected function, we're allowed to do so. -			 */ -			if (!zend_check_protected(destructor->common.scope, EG(scope))) { -				zend_error(E_ERROR, "Call to protected destructor from context '%s'", EG(scope) ? EG(scope)->name : ""); -			} -		} - -		ZEND_INIT_SYMTABLE(&symbol_table); -		  		call_user_function_ex(NULL, &obj, destructor_func_name, &retval_ptr, 0, NULL, 0, &symbol_table TSRMLS_CC);  		zend_hash_destroy(&symbol_table); @@ -71,16 +84,7 @@ static inline void zend_objects_call_destructor(zend_object *object, zend_object  			zval_ptr_dtor(&retval_ptr);  		}  	} -} - - -ZEND_API void zend_objects_destroy_object(zend_object *object, zend_object_handle handle TSRMLS_DC) -{ -	zend_objects_call_destructor(object, handle TSRMLS_CC); -	/* Nuke the object */ -	zend_hash_destroy(object->properties); -	FREE_HASHTABLE(object->properties); -	efree(object); +	zend_nuke_object(object TSRMLS_CC);  }  ZEND_API zend_object_value zend_objects_new(zend_object **object, zend_class_entry *class_type TSRMLS_DC) | 
