summaryrefslogtreecommitdiff
path: root/Zend/zend_object_handlers.c
diff options
context:
space:
mode:
Diffstat (limited to 'Zend/zend_object_handlers.c')
-rw-r--r--Zend/zend_object_handlers.c33
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);
}
}