From: Dmitry Stogov Date: Fri, 17 Oct 2008 10:26:16 +0000 (+0000) Subject: Fixed bug #46308 (Invalid write when changing property from inside getter) X-Git-Tag: BEFORE_HEAD_NS_CHANGE~207 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f870cd858954b3fddf9a9d7a229a8db2723b2791;p=php Fixed bug #46308 (Invalid write when changing property from inside getter) --- diff --git a/Zend/tests/bug46308.phpt b/Zend/tests/bug46308.phpt new file mode 100644 index 0000000000..37227385c7 --- /dev/null +++ b/Zend/tests/bug46308.phpt @@ -0,0 +1,33 @@ +--TEST-- +Bug #46308 (Invalid write when changing property from inside getter) +--FILE-- +bar; +echo "ok\n"; +?> +--EXPECT-- +ok diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index fddf991c13..6144b2a632 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -353,6 +353,7 @@ zval *zend_std_read_property(zval *object, zval *member, int type TSRMLS_DC) /* zend_get_property_guard(zobj, property_info, member, &guard TSRMLS_CC) == SUCCESS && !guard->in_get) { /* have getter - try with it! */ + Z_ADDREF_P(object); guard->in_get = 1; /* prevent circular getting */ rv = zend_std_call_getter(object, member TSRMLS_CC); guard->in_get = 0; @@ -377,6 +378,7 @@ zval *zend_std_read_property(zval *object, zval *member, int type TSRMLS_DC) /* } else { retval = &EG(uninitialized_zval_ptr); } + zval_ptr_dtor(&object); } else { if (!silent) { zend_error(E_NOTICE,"Undefined property: %v::$%R", zobj->ce->name, Z_TYPE_P(member), Z_STRVAL_P(member)); @@ -447,12 +449,14 @@ static void zend_std_write_property(zval *object, zval *member, zval *value TSRM if (zobj->ce->__set && zend_get_property_guard(zobj, property_info, member, &guard TSRMLS_CC) == SUCCESS && !guard->in_set) { + Z_ADDREF_P(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) { zval **foo; @@ -628,9 +632,11 @@ static void zend_std_unset_property(zval *object, zval *member TSRMLS_DC) /* {{{ zend_get_property_guard(zobj, property_info, member, &guard TSRMLS_CC) == SUCCESS && !guard->in_unset) { /* have unseter - try with it! */ + Z_ADDREF_P(object); guard->in_unset = 1; /* prevent circular unsetting */ zend_std_call_unsetter(object, member TSRMLS_CC); guard->in_unset = 0; + zval_ptr_dtor(&object); } } @@ -1146,6 +1152,7 @@ static int zend_std_has_property(zval *object, zval *member, int has_set_exists zval *rv; /* have issetter - try with it! */ + Z_ADDREF_P(object); guard->in_isset = 1; /* prevent circular getting */ rv = zend_std_call_issetter(object, member TSRMLS_CC); if (rv) { @@ -1169,6 +1176,7 @@ static int zend_std_has_property(zval *object, zval *member, int has_set_exists } } guard->in_isset = 0; + zval_ptr_dtor(&object); } } else { switch (has_set_exists) {