diff options
author | Dmitry Stogov <dmitry@php.net> | 2008-10-17 10:25:56 +0000 |
---|---|---|
committer | Dmitry Stogov <dmitry@php.net> | 2008-10-17 10:25:56 +0000 |
commit | 739c75b05077a08176a12b77db1d72aa17b2971d (patch) | |
tree | 8791083cd8736c1efbf3cfe2e2467b0316a3c22f | |
parent | 0621602408f75d01a213bdd0fb61d311457ea280 (diff) | |
download | php-git-739c75b05077a08176a12b77db1d72aa17b2971d.tar.gz |
Fixed bug #46308 (Invalid write when changing property from inside getter)
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | Zend/tests/bug46308.phpt | 33 | ||||
-rw-r--r-- | Zend/zend_object_handlers.c | 8 |
3 files changed, 43 insertions, 0 deletions
@@ -3,6 +3,8 @@ PHP NEWS ?? Oct 2008, PHP 5.2.7RC2 - Fixed bug #46319 (PHP sets default Content-Type header for HTTP 304 response code, in cgi sapi). (Ilia) +- Fixed bug #46308 (Invalid write when changing property from inside getter). + (Dmitry) - Fixed bug #46292 (PDO::setFetchMode() shouldn't requires the 2nd arg when using FETCH_CLASSTYPE). (Felipe) - Fixed bug #46274, #46249 (pdo_pgsql always fill in NULL for empty BLOB and 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-- +<?php +class main +{ + public static $dummy = NULL ; + public static $dataAccessor = NULL ; +} + +class dataAccessor +{ +} + +class relay +{ + public function __get( $name ) + { + main::$dataAccessor = new dataAccessor; + } +} + +class dummy +{ +} + +main::$dummy = new dummy(); +main::$dataAccessor = new relay(); +main::$dataAccessor->bar; +echo "ok\n"; +?> +--EXPECT-- +ok diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 42b687eff7..044f21b92f 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -328,6 +328,7 @@ zval *zend_std_read_property(zval *object, zval *member, int type TSRMLS_DC) zend_get_property_guard(zobj, property_info, member, &guard) == SUCCESS && !guard->in_get) { /* have getter - try with it! */ + ZVAL_ADDREF(object); guard->in_get = 1; /* prevent circular getting */ rv = zend_std_call_getter(object, member TSRMLS_CC); guard->in_get = 0; @@ -352,6 +353,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: %s::$%s", zobj->ce->name, Z_STRVAL_P(member)); @@ -422,12 +424,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) == SUCCESS && !guard->in_set) { + ZVAL_ADDREF(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; @@ -602,9 +606,11 @@ static void zend_std_unset_property(zval *object, zval *member TSRMLS_DC) zend_get_property_guard(zobj, property_info, member, &guard) == SUCCESS && !guard->in_unset) { /* have unseter - try with it! */ + ZVAL_ADDREF(object); guard->in_unset = 1; /* prevent circular unsetting */ zend_std_call_unsetter(object, member TSRMLS_CC); guard->in_unset = 0; + zval_ptr_dtor(&object); } } @@ -1020,6 +1026,7 @@ static int zend_std_has_property(zval *object, zval *member, int has_set_exists zval *rv; /* have issetter - try with it! */ + ZVAL_ADDREF(object); guard->in_isset = 1; /* prevent circular getting */ rv = zend_std_call_issetter(object, member TSRMLS_CC); if (rv) { @@ -1037,6 +1044,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) { |