summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2016-05-13 11:55:09 +0300
committerDmitry Stogov <dmitry@zend.com>2016-05-13 11:55:09 +0300
commite9c3f9fcde1013cc1c9bdead7e16478a108d7907 (patch)
tree0febdec537962f48a78e5e5e74d44a585240b75a
parentee8f402af8c964acac5740ee1677a7b47e20a883 (diff)
downloadphp-git-e9c3f9fcde1013cc1c9bdead7e16478a108d7907.tar.gz
Fixed bug #72177 (Scope issue in __destruct after ReflectionProperty::setValue())
-rw-r--r--Zend/tests/bug72177.phpt35
-rw-r--r--Zend/tests/bug72177_2.phpt34
-rw-r--r--Zend/zend_object_handlers.c20
-rw-r--r--Zend/zend_objects.c7
4 files changed, 96 insertions, 0 deletions
diff --git a/Zend/tests/bug72177.phpt b/Zend/tests/bug72177.phpt
new file mode 100644
index 0000000000..b5658d354a
--- /dev/null
+++ b/Zend/tests/bug72177.phpt
@@ -0,0 +1,35 @@
+--TEST--
+Bug #72177 Scope issue in __destruct after ReflectionProperty::setValue()
+--FILE--
+<?php
+class Child
+{
+ protected $bar;
+
+ public function __destruct()
+ {
+ $this->bar = null;
+ }
+}
+
+class Parnt
+{
+ protected $child;
+
+ public function doSomething()
+ {
+ $this->child = new Child();
+
+ $prop = new \ReflectionProperty($this, 'child');
+ $prop->setAccessible(true);
+ $prop->setValue($this, null);
+ }
+}
+
+$p = new Parnt();
+$p->doSomething();
+
+echo "OK\n";
+?>
+--EXPECT--
+OK
diff --git a/Zend/tests/bug72177_2.phpt b/Zend/tests/bug72177_2.phpt
new file mode 100644
index 0000000000..718d6c061e
--- /dev/null
+++ b/Zend/tests/bug72177_2.phpt
@@ -0,0 +1,34 @@
+--TEST--
+Bug #72177 Scope issue in __destruct after ReflectionProperty::setValue()
+--FILE--
+<?php
+class Foo
+{
+ private $bar = 'bar';
+
+ public function __construct()
+ {
+ unset($this->bar);
+ }
+}
+
+class Bar extends Foo
+{
+ private $baz = 'baz';
+ private static $tab = 'tab';
+
+ public function __get(string $name)
+ {
+ var_dump($this->baz);
+ var_dump(self::$tab);
+ return $name;
+ }
+}
+
+$r = new ReflectionProperty(Foo::class, 'bar');
+
+$r->setAccessible(true);
+echo "OK\n";
+?>
+--EXPECT--
+OK
diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c
index 47fc542dbc..6aa5d731c5 100644
--- a/Zend/zend_object_handlers.c
+++ b/Zend/zend_object_handlers.c
@@ -191,6 +191,9 @@ ZEND_API HashTable *zend_std_get_debug_info(zval *object, int *is_temp) /* {{{ *
static void zend_std_call_getter(zval *object, zval *member, zval *retval) /* {{{ */
{
zend_class_entry *ce = Z_OBJCE_P(object);
+ zend_class_entry *orig_fake_scope = EG(fake_scope);
+
+ EG(fake_scope) = NULL;
/* __get handler is called with one argument:
property name
@@ -202,6 +205,8 @@ static void zend_std_call_getter(zval *object, zval *member, zval *retval) /* {{
zend_call_method_with_1_params(object, ce, &ce->__get, ZEND_GET_FUNC_NAME, retval, member);
zval_ptr_dtor(member);
+
+ EG(fake_scope) = orig_fake_scope;
}
/* }}} */
@@ -210,6 +215,9 @@ static int zend_std_call_setter(zval *object, zval *member, zval *value) /* {{{
zval retval;
int result;
zend_class_entry *ce = Z_OBJCE_P(object);
+ zend_class_entry *orig_fake_scope = EG(fake_scope);
+
+ EG(fake_scope) = NULL;
if (Z_REFCOUNTED_P(member)) Z_ADDREF_P(member);
if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
@@ -228,8 +236,10 @@ static int zend_std_call_setter(zval *object, zval *member, zval *value) /* {{{
if (Z_TYPE(retval) != IS_UNDEF) {
result = i_zend_is_true(&retval) ? SUCCESS : FAILURE;
zval_ptr_dtor(&retval);
+ EG(fake_scope) = orig_fake_scope;
return result;
} else {
+ EG(fake_scope) = orig_fake_scope;
return FAILURE;
}
}
@@ -238,6 +248,9 @@ static int zend_std_call_setter(zval *object, zval *member, zval *value) /* {{{
static void zend_std_call_unsetter(zval *object, zval *member) /* {{{ */
{
zend_class_entry *ce = Z_OBJCE_P(object);
+ zend_class_entry *orig_fake_scope = EG(fake_scope);
+
+ EG(fake_scope) = NULL;
/* __unset handler is called with one argument:
property name
@@ -248,12 +261,17 @@ static void zend_std_call_unsetter(zval *object, zval *member) /* {{{ */
zend_call_method_with_1_params(object, ce, &ce->__unset, ZEND_UNSET_FUNC_NAME, NULL, member);
zval_ptr_dtor(member);
+
+ EG(fake_scope) = orig_fake_scope;
}
/* }}} */
static void zend_std_call_issetter(zval *object, zval *member, zval *retval) /* {{{ */
{
zend_class_entry *ce = Z_OBJCE_P(object);
+ zend_class_entry *orig_fake_scope = EG(fake_scope);
+
+ EG(fake_scope) = NULL;
/* __isset handler is called with one argument:
property name
@@ -266,6 +284,8 @@ static void zend_std_call_issetter(zval *object, zval *member, zval *retval) /*
zend_call_method_with_1_params(object, ce, &ce->__isset, ZEND_ISSET_FUNC_NAME, retval, member);
zval_ptr_dtor(member);
+
+ EG(fake_scope) = orig_fake_scope;
}
/* }}} */
diff --git a/Zend/zend_objects.c b/Zend/zend_objects.c
index 53d215d27e..b5f19b3045 100644
--- a/Zend/zend_objects.c
+++ b/Zend/zend_objects.c
@@ -91,7 +91,9 @@ ZEND_API void zend_objects_destroy_object(zend_object *object)
if (destructor) {
zend_object *old_exception;
zval obj;
+ zend_class_entry *orig_fake_scope = NULL;
+ EG(fake_scope) = NULL;
if (destructor->op_array.fn_flags & (ZEND_ACC_PRIVATE|ZEND_ACC_PROTECTED)) {
if (destructor->op_array.fn_flags & ZEND_ACC_PRIVATE) {
/* Ensure that if we're calling a private function, we're allowed to do so.
@@ -104,12 +106,14 @@ ZEND_API void zend_objects_destroy_object(zend_object *object)
"Call to private %s::__destruct() from context '%s'",
ZSTR_VAL(object->ce->name),
scope ? ZSTR_VAL(scope->name) : "");
+ EG(fake_scope) = orig_fake_scope;
return;
}
} else {
zend_error(E_WARNING,
"Call to private %s::__destruct() from context '' during shutdown ignored",
ZSTR_VAL(object->ce->name));
+ EG(fake_scope) = orig_fake_scope;
return;
}
} else {
@@ -123,12 +127,14 @@ ZEND_API void zend_objects_destroy_object(zend_object *object)
"Call to protected %s::__destruct() from context '%s'",
ZSTR_VAL(object->ce->name),
scope ? ZSTR_VAL(scope->name) : "");
+ EG(fake_scope) = orig_fake_scope;
return;
}
} else {
zend_error(E_WARNING,
"Call to protected %s::__destruct() from context '' during shutdown ignored",
ZSTR_VAL(object->ce->name));
+ EG(fake_scope) = orig_fake_scope;
return;
}
}
@@ -159,6 +165,7 @@ ZEND_API void zend_objects_destroy_object(zend_object *object)
}
}
zval_ptr_dtor(&obj);
+ EG(fake_scope) = orig_fake_scope;
}
}