php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #72177 Scope issue in __destruct after ReflectionProperty::setValue()
Submitted: 2016-05-09 13:28 UTC Modified: 2016-05-12 21:23 UTC
From: lbarnaud@php.net Assigned: dmitry (profile)
Status: Closed Package: Reflection related
PHP Version: 7.0Git-2016-05-09 (Git) OS:
Private report: No CVE-ID: None
 [2016-05-09 13:28 UTC] lbarnaud@php.net
Description:
------------
When __destruct() is called, following a ReflectionProperty::setValue() call, scopes seem to be wrong.

In the following reproducing script, the method `Child::__destruct()` fails to set `$this->bar to null`, with the error `Cannot access protected property Child::$bar`.

I can reproduce this in git master, but not in any version from 3v4l.org.

Test script:
---------------
<?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";

Expected result:
----------------
OK

Actual result:
--------------
Fatal error: Uncaught Error: Cannot access protected property Child::$bar in /tmp/x.php:9
Stack trace:
#0 [internal function]: Child->__destruct()
#1 /tmp/x.php(23): ReflectionProperty->setValue(Object(Parnt), NULL)
#2 /tmp/x.php(28): Parnt->doSomething()
#3 {main}
  thrown in /tmp/x.php on line 9

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-05-12 15:48 UTC] nikic@php.net
-Status: Open +Status: Assigned -Assigned To: +Assigned To: dmitry
 [2016-05-12 15:48 UTC] nikic@php.net
Fallout from the EG(scope) removal. Now EG(fake_scope) will continue shadowing the scope, even though we might reenter a differently scoped method.

This looks a bit tricky... maybe we should just avoid the fake scoping altogether and add an extra scope argument to the property handlers?
 [2016-05-12 21:43 UTC] ocramius at gmail dot com
Related: I got similar failures when accessing object state via `__get`, when `__get` is triggered by reflection, as the scope with which `__get` is called is wrong.
Specifically, something like following:

=====foo.php======
<?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);

var_dump($r->getValue(new Bar));
=====/foo.php======

This will work in 7.0.0~7.0.7 (see https://3v4l.org/dQlsf), but will crash on master (7.1.0-DEV), with something like following:

=====OUTPUT======
NULL

Fatal error: Uncaught Error: Cannot access private property Bar::$tab in foo.php:21
Stack trace:
#0 foo.php(20): Bar->__get('baz')
#1 [internal function]: Bar->__get('bar')
#2 foo.php(30): ReflectionProperty->getValue(Object(Bar))
#3 {main}
  thrown in /Users/ocramius/Documents/Projects/ProxyManager/foo.php on line 21
=====/OUTPUT======
 [2016-05-13 08:55 UTC] dmitry@php.net
Automatic comment on behalf of dmitry@zend.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=e9c3f9fcde1013cc1c9bdead7e16478a108d7907
Log: Fixed bug #72177 (Scope issue in __destruct after ReflectionProperty::setValue())
 [2016-05-13 08:55 UTC] dmitry@php.net
-Status: Assigned +Status: Closed
 [2016-07-20 11:31 UTC] davey@php.net
Automatic comment on behalf of dmitry@zend.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=e9c3f9fcde1013cc1c9bdead7e16478a108d7907
Log: Fixed bug #72177 (Scope issue in __destruct after ReflectionProperty::setValue())
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Apr 20 06:01:28 2024 UTC