diff options
Diffstat (limited to 'Zend/zend_object_handlers.c')
-rw-r--r-- | Zend/zend_object_handlers.c | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index ff8ee732e9..0097f45b87 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -542,7 +542,7 @@ ZEND_API uint32_t *zend_get_property_guard(zend_object *zobj, zend_string *membe zval *zend_std_read_property(zval *object, zval *member, int type, void **cache_slot, zval *rv) /* {{{ */ { zend_object *zobj; - zval tmp_member; + zval tmp_member, tmp_object; zval *retval; uintptr_t property_offset; uint32_t *guard = NULL; @@ -602,20 +602,28 @@ zval *zend_std_read_property(zval *object, zval *member, int type, void **cache_ goto exit; } + ZVAL_UNDEF(&tmp_object); + /* magic isset */ if ((type == BP_VAR_IS) && zobj->ce->__isset) { zval tmp_result; guard = zend_get_property_guard(zobj, Z_STR_P(member)); if (!((*guard) & IN_ISSET)) { + if (Z_TYPE(tmp_member) == IS_UNDEF) { + ZVAL_COPY(&tmp_member, member); + member = &tmp_member; + } + ZVAL_COPY(&tmp_object, object); ZVAL_UNDEF(&tmp_result); *guard |= IN_ISSET; - zend_std_call_issetter(object, member, &tmp_result); + zend_std_call_issetter(&tmp_object, member, &tmp_result); *guard &= ~IN_ISSET; if (!zend_is_true(&tmp_result)) { retval = &EG(uninitialized_zval); + zval_ptr_dtor(&tmp_object); zval_ptr_dtor(&tmp_result); goto exit; } @@ -631,8 +639,11 @@ zval *zend_std_read_property(zval *object, zval *member, int type, void **cache_ } if (!((*guard) & IN_GET)) { /* have getter - try with it! */ + if (Z_TYPE(tmp_object) == IS_UNDEF) { + ZVAL_COPY(&tmp_object, object); + } *guard |= IN_GET; /* prevent circular getting */ - zend_std_call_getter(object, member, rv); + zend_std_call_getter(&tmp_object, member, rv); *guard &= ~IN_GET; if (Z_TYPE_P(rv) != IS_UNDEF) { @@ -647,15 +658,20 @@ zval *zend_std_read_property(zval *object, zval *member, int type, void **cache_ } else { retval = &EG(uninitialized_zval); } + zval_ptr_dtor(&tmp_object); goto exit; } else { if (Z_STRVAL_P(member)[0] == '\0' && Z_STRLEN_P(member) != 0) { + zval_ptr_dtor(&tmp_object); zend_throw_error(NULL, "Cannot access property started with '\\0'"); retval = &EG(uninitialized_zval); goto exit; } } } + + zval_ptr_dtor(&tmp_object); + if ((type != BP_VAR_IS)) { zend_error(E_NOTICE,"Undefined property: %s::$%s", ZSTR_VAL(zobj->ce->name), Z_STRVAL_P(member)); } @@ -1570,17 +1586,23 @@ found: if (!((*guard) & IN_ISSET)) { zval rv; + zval tmp_object; /* have issetter - try with it! */ + if (Z_TYPE(tmp_member) == IS_UNDEF) { + ZVAL_COPY(&tmp_member, member); + member = &tmp_member; + } + ZVAL_COPY(&tmp_object, object); (*guard) |= IN_ISSET; /* prevent circular getting */ - zend_std_call_issetter(object, member, &rv); + zend_std_call_issetter(&tmp_object, member, &rv); if (Z_TYPE(rv) != IS_UNDEF) { result = zend_is_true(&rv); zval_ptr_dtor(&rv); if (has_set_exists && result) { if (EXPECTED(!EG(exception)) && zobj->ce->__get && !((*guard) & IN_GET)) { (*guard) |= IN_GET; - zend_std_call_getter(object, member, &rv); + zend_std_call_getter(&tmp_object, member, &rv); (*guard) &= ~IN_GET; if (Z_TYPE(rv) != IS_UNDEF) { result = i_zend_is_true(&rv); @@ -1594,6 +1616,7 @@ found: } } (*guard) &= ~IN_ISSET; + zval_ptr_dtor(&tmp_object); } } |