summaryrefslogtreecommitdiff
path: root/Zend/zend_object_handlers.c
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@php.net>2010-10-01 09:49:20 +0000
committerDmitry Stogov <dmitry@php.net>2010-10-01 09:49:20 +0000
commit4d8503a2122ec7b3489878d09b17fb5f29bc92b0 (patch)
treec74cc6dbe55e6adf3b47dd0ba30497c38e60afd8 /Zend/zend_object_handlers.c
parentbc6e920ebc93a137581d8d9cdd378f1e4f8f6f22 (diff)
downloadphp-git-4d8503a2122ec7b3489878d09b17fb5f29bc92b0.tar.gz
Fixed bug #52879 (Objects unreferenced in __get, __set, __isset or __unset can be freed too early). (mail_ben_schmidt at yahoo dot com dot au, Dmitry)
Diffstat (limited to 'Zend/zend_object_handlers.c')
-rw-r--r--Zend/zend_object_handlers.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c
index b91fcd0787..291655027f 100644
--- a/Zend/zend_object_handlers.c
+++ b/Zend/zend_object_handlers.c
@@ -347,6 +347,9 @@ zval *zend_std_read_property(zval *object, zval *member, int type TSRMLS_DC) /*
!guard->in_get) {
/* have getter - try with it! */
Z_ADDREF_P(object);
+ if (PZVAL_IS_REF(object)) {
+ SEPARATE_ZVAL(&object);
+ }
guard->in_get = 1; /* prevent circular getting */
rv = zend_std_call_getter(object, member TSRMLS_CC);
guard->in_get = 0;
@@ -445,22 +448,22 @@ static void zend_std_write_property(zval *object, zval *member, zval *value TSRM
}
}
} else {
- int setter_done = 0;
zend_guard *guard = NULL;
if (zobj->ce->__set &&
zend_get_property_guard(zobj, property_info, member, &guard) == SUCCESS &&
!guard->in_set) {
Z_ADDREF_P(object);
+ if (PZVAL_IS_REF(object)) {
+ SEPARATE_ZVAL(&object);
+ }
guard->in_set = 1; /* prevent circular setting */
if (zend_std_call_setter(object, member, value TSRMLS_CC) != SUCCESS) {
/* for now, just ignore it - __set should take care of warnings, etc. */
}
- setter_done = 1;
guard->in_set = 0;
zval_ptr_dtor(&object);
- }
- if (!setter_done && property_info) {
+ } else if (property_info) {
zval **foo;
/* if we assign referenced variable, we should separate it */
@@ -643,6 +646,9 @@ static void zend_std_unset_property(zval *object, zval *member TSRMLS_DC) /* {{{
!guard->in_unset) {
/* have unseter - try with it! */
Z_ADDREF_P(object);
+ if (PZVAL_IS_REF(object)) {
+ SEPARATE_ZVAL(&object);
+ }
guard->in_unset = 1; /* prevent circular unsetting */
zend_std_call_unsetter(object, member TSRMLS_CC);
guard->in_unset = 0;
@@ -1169,6 +1175,9 @@ static int zend_std_has_property(zval *object, zval *member, int has_set_exists
/* have issetter - try with it! */
Z_ADDREF_P(object);
+ if (PZVAL_IS_REF(object)) {
+ SEPARATE_ZVAL(&object);
+ }
guard->in_isset = 1; /* prevent circular getting */
rv = zend_std_call_issetter(object, member TSRMLS_CC);
if (rv) {