From 739c75b05077a08176a12b77db1d72aa17b2971d Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 17 Oct 2008 10:25:56 +0000 Subject: [PATCH] Fixed bug #46308 (Invalid write when changing property from inside getter) --- NEWS | 2 ++ Zend/tests/bug46308.phpt | 33 +++++++++++++++++++++++++++++++++ Zend/zend_object_handlers.c | 8 ++++++++ 3 files changed, 43 insertions(+) create mode 100644 Zend/tests/bug46308.phpt diff --git a/NEWS b/NEWS index d15dab5137..e4e1afe306 100644 --- a/NEWS +++ b/NEWS @@ -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-- +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) { -- 2.50.1