php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #46718 ReflectionProperty::setValue() and ReflectionProperty::setAccessible()
Submitted: 2008-11-29 14:48 UTC Modified: 2008-11-29 15:59 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: sebastian@php.net Assigned:
Status: Closed Package: Reflection related
PHP Version: 5.3CVS-2008-11-29 (CVS) OS: irrelevant
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: sebastian@php.net
New email:
PHP Version: OS:

 

 [2008-11-29 14:48 UTC] sebastian@php.net
Description:
------------
ReflectionProperty::setValue() ignores the setting made with ReflectionProperty::setAccessible(TRUE).

Reproduce code:
---------------
<?php
class A {
    protected $protected = 'a';
    protected static $protectedStatic = 'b';
    private $private = 'c';
    private static $privateStatic = 'd';
}

$a               = new A;
$protected       = new ReflectionProperty($a, 'protected');
$protectedStatic = new ReflectionProperty('A', 'protectedStatic');
$private         = new ReflectionProperty($a, 'private');
$privateStatic   = new ReflectionProperty('A', 'privateStatic');

try {
    var_dump($protected->getValue($a));
}

catch (ReflectionException $e) {
    var_dump($e->getMessage());
}

try {
    var_dump($protectedStatic->getValue());
}

catch (ReflectionException $e) {
    var_dump($e->getMessage());
}

try {
    var_dump($private->getValue($a));
}

catch (ReflectionException $e) {
    var_dump($e->getMessage());
}

try {
    var_dump($privateStatic->getValue());
}

catch (ReflectionException $e) {
    var_dump($e->getMessage());
}

$protected->setAccessible(TRUE);
$protectedStatic->setAccessible(TRUE);
$private->setAccessible(TRUE);
$privateStatic->setAccessible(TRUE);

var_dump($protected->getValue($a));
var_dump($protectedStatic->getValue());
var_dump($private->getValue($a));
var_dump($privateStatic->getValue());

$protected->setValue($a, 'e');
$protectedStatic->setValue('f');
$private->setValue($a, 'g');
$privateStatic->setValue('h');

var_dump($protected->getValue($a));
var_dump($protectedStatic->getValue());
var_dump($private->getValue($a));
var_dump($privateStatic->getValue());
?>

Expected result:
----------------
string(44) "Cannot access non-public member A::protected"
string(50) "Cannot access non-public member A::protectedStatic"
string(42) "Cannot access non-public member A::private"
string(48) "Cannot access non-public member A::privateStatic"
string(1) "a"
string(1) "b"
string(1) "c"
string(1) "d"
string(1) "e"
string(1) "f"
string(1) "g"
string(1) "h"

Actual result:
--------------
string(44) "Cannot access non-public member A::protected"
string(50) "Cannot access non-public member A::protectedStatic"
string(42) "Cannot access non-public member A::private"
string(48) "Cannot access non-public member A::privateStatic"
string(1) "a"
string(1) "b"
string(1) "c"
string(1) "d"

ReflectionException: Cannot access non-public member A::protected in /usr/local/src/php/php-5.3/reflectionProperty_setAccessible.php on line 57

Call Stack:
    0.0010     355044   1. {main}() /usr/local/src/php/php-5.3/reflectionProperty_setAccessible.php:0
    0.0294     365972   2. ReflectionProperty->setValue() /usr/local/src/php/php-5.3/reflectionProperty_setAccessible.php:57

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2008-11-29 14:49 UTC] sebastian@php.net
Here is a patch that implements the missing functionality in ReflectionProperty::setValue().

Index: php_reflection.c
===================================================================
RCS file: /repository/php-src/ext/reflection/php_reflection.c,v
retrieving revision 1.164.2.33.2.45.2.42
diff -u -B -u -r1.164.2.33.2.45.2.42 php_reflection.c
--- php_reflection.c    27 Nov 2008 19:01:22 -0000      1.164.2.33.2.45.2.42
+++ php_reflection.c    29 Nov 2008 14:44:52 -0000
@@ -4365,7 +4365,7 @@
        METHOD_NOTSTATIC(reflection_property_ptr);
        GET_REFLECTION_OBJECT_PTR(ref);

-       if (!(ref->prop.flags & ZEND_ACC_PUBLIC)) {
+       if (!(ref->prop.flags & ZEND_ACC_PUBLIC) && ref->ignore_visibility == 0) {
                _default_get_entry(getThis(), "name", sizeof("name"), &name TSRMLS_CC);
                zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
                        "Cannot access non-public member %s::%s", intern->ce->name, Z_STRVAL(name));
@@ -4409,10 +4409,13 @@
                        zend_hash_quick_update(prop_table, ref->prop.name, ref->prop.name_length+1, ref->prop.h, &value, sizeof(zval *), (void **) &foo);
                }
        } else {
+               char *class_name, *prop_name;
+
                if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "oz", &object, &value) == FAILURE) {
                        return;
                }
-               zend_update_property(Z_OBJCE_P(object), object, ref->prop.name, ref->prop.name_length, value TSRMLS_CC);
+               zend_unmangle_property_name(ref->prop.name, ref->prop.name_length, &class_name, &prop_name);
+               zend_update_property(Z_OBJCE_P(object), object, prop_name, strlen(prop_name), value TSRMLS_CC);
        }
 }
 /* }}} */
Index: tests/reflectionProperty_setAccessible.phpt
===================================================================
RCS file: /repository/php-src/ext/reflection/tests/reflectionProperty_setAccessible.phpt,v
retrieving revision 1.1.2.3
diff -u -B -u -r1.1.2.3 reflectionProperty_setAccessible.phpt
--- tests/reflectionProperty_setAccessible.phpt 24 May 2008 13:34:22 -0000      1.1.2.3
+++ tests/reflectionProperty_setAccessible.phpt 29 Nov 2008 14:44:52 -0000
@@ -2,43 +2,82 @@
 Test ReflectionProperty::setAccessible().
 --FILE--
 <?php
-
-class TestClass {
-    public $pub;
-    public $pub2 = 5;
-    static public $stat = "static property";
-    protected $prot = 4;
-    private $priv = "keepOut";
+class A {
+    protected $protected = 'a';
+    protected static $protectedStatic = 'b';
+    private $private = 'c';
+    private static $privateStatic = 'd';
 }

-class AnotherClass {
+$a               = new A;
+$protected       = new ReflectionProperty($a, 'protected');
+$protectedStatic = new ReflectionProperty('A', 'protectedStatic');
+$private         = new ReflectionProperty($a, 'private');
+$privateStatic   = new ReflectionProperty('A', 'privateStatic');
+
+try {
+    var_dump($protected->getValue($a));
 }

-$instance = new TestClass();
+catch (ReflectionException $e) {
+    var_dump($e->getMessage());
+}

-echo "\nProtected property:\n";
-$propInfo = new ReflectionProperty('TestClass', 'prot');
 try {
-    var_dump($propInfo->getValue($instance));
+    var_dump($protectedStatic->getValue());
 }
-catch(Exception $exc) {
-    echo $exc->getMessage(), "\n";
+
+catch (ReflectionException $e) {
+    var_dump($e->getMessage());
+}
+
+try {
+    var_dump($private->getValue($a));
 }

-$propInfo->setAccessible(true);
-var_dump($propInfo->getValue($instance));
+catch (ReflectionException $e) {
+    var_dump($e->getMessage());
+}

-$propInfo->setAccessible(false);
 try {
-    var_dump($propInfo->getValue($instance));
+    var_dump($privateStatic->getValue());
 }
-catch(Exception $exc) {
-    echo $exc->getMessage(), "\n";
+
+catch (ReflectionException $e) {
+    var_dump($e->getMessage());
 }
+
+$protected->setAccessible(TRUE);
+$protectedStatic->setAccessible(TRUE);
+$private->setAccessible(TRUE);
+$privateStatic->setAccessible(TRUE);
+
+var_dump($protected->getValue($a));
+var_dump($protectedStatic->getValue());
+var_dump($private->getValue($a));
+var_dump($privateStatic->getValue());
+
+$protected->setValue($a, 'e');
+$protectedStatic->setValue('f');
+$private->setValue($a, 'g');
+$privateStatic->setValue('h');
+
+var_dump($protected->getValue($a));
+var_dump($protectedStatic->getValue());
+var_dump($private->getValue($a));
+var_dump($privateStatic->getValue());
 ?>
 --EXPECTF--
+string(44) "Cannot access non-public member A::protected"
+string(50) "Cannot access non-public member A::protectedStatic"
+string(42) "Cannot access non-public member A::private"
+string(48) "Cannot access non-public member A::privateStatic"
+string(1) "a"
+string(1) "b"
+string(1) "c"
+string(1) "d"
+string(1) "e"
+string(1) "f"
+string(1) "g"
+string(1) "h"

-Protected property:
-Cannot access non-public member TestClass::prot
-int(4)
-Cannot access non-public member TestClass::prot
 [2008-11-29 15:59 UTC] sebastian@php.net
This bug has been fixed in CVS.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.


 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Dec 22 12:01:30 2024 UTC