sebastian                                Wed, 16 Sep 2009 17:24:46 +0000

Revision: http://svn.php.net/viewvc?view=revision&revision=288380

Log:
Merge ReflectionMethod::setAccessible() to PHP 5.3.2, approved by Johannes.

Changed paths:
    U   php/php-src/branches/PHP_5_3/NEWS
    U   php/php-src/branches/PHP_5_3/ext/reflection/php_reflection.c
    A + 
php/php-src/branches/PHP_5_3/ext/reflection/tests/ReflectionMethod_setAccessible.phpt
        (from 
php/php-src/trunk/ext/reflection/tests/ReflectionMethod_setAccessible.phpt:r288379)
    U   php/php-src/trunk/NEWS

Modified: php/php-src/branches/PHP_5_3/NEWS
===================================================================
--- php/php-src/branches/PHP_5_3/NEWS	2009-09-16 17:03:44 UTC (rev 288379)
+++ php/php-src/branches/PHP_5_3/NEWS	2009-09-16 17:24:46 UTC (rev 288380)
@@ -1,6 +1,8 @@
 PHP                                                                        NEWS
 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 ?? ??? 2009, PHP 5.3.2
+- Added ReflectionMethod::setAccessible() for invoking non-public methods
+  through the Reflection API. (Sebastian)
 - Implemented FR #49253 (added support for libcurl's CERTINFO option).
   (Linus Nielsen Feltzing <li...@haxx.se>)


Modified: php/php-src/branches/PHP_5_3/ext/reflection/php_reflection.c
===================================================================
--- php/php-src/branches/PHP_5_3/ext/reflection/php_reflection.c	2009-09-16 17:03:44 UTC (rev 288379)
+++ php/php-src/branches/PHP_5_3/ext/reflection/php_reflection.c	2009-09-16 17:24:46 UTC (rev 288380)
@@ -176,7 +176,6 @@
 typedef struct _property_reference {
 	zend_class_entry *ce;
 	zend_property_info prop;
-	unsigned int ignore_visibility:1;
 } property_reference;

 /* Struct for parameters */
@@ -201,6 +200,7 @@
 	reflection_type_t ref_type;
 	zval *obj;
 	zend_class_entry *ce;
+	unsigned int ignore_visibility:1;
 } reflection_object;

 static zend_object_handlers reflection_object_handlers;
@@ -1290,10 +1290,10 @@
 	reference = (property_reference*) emalloc(sizeof(property_reference));
 	reference->ce = ce;
 	reference->prop = *prop;
-	reference->ignore_visibility = 0;
 	intern->ptr = reference;
 	intern->ref_type = REF_TYPE_PROPERTY;
 	intern->ce = ce;
+	intern->ignore_visibility = 0;
 	zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
 	zend_hash_update(Z_OBJPROP_P(object), "class", sizeof("class"), (void **) &classname, sizeof(zval *), NULL);
 }
@@ -2561,8 +2561,9 @@

 	GET_REFLECTION_OBJECT_PTR(mptr);

-	if (!(mptr->common.fn_flags & ZEND_ACC_PUBLIC)
-		|| (mptr->common.fn_flags & ZEND_ACC_ABSTRACT))
+	if ((!(mptr->common.fn_flags & ZEND_ACC_PUBLIC)
+		 || (mptr->common.fn_flags & ZEND_ACC_ABSTRACT))
+		 && intern->ignore_visibility == 0)
 	{
 		if (mptr->common.fn_flags & ZEND_ACC_ABSTRACT) {
 			zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
@@ -2669,8 +2670,9 @@
 		return;
 	}

-	if (!(mptr->common.fn_flags & ZEND_ACC_PUBLIC)
-		|| (mptr->common.fn_flags & ZEND_ACC_ABSTRACT))
+	if ((!(mptr->common.fn_flags & ZEND_ACC_PUBLIC)
+		 || (mptr->common.fn_flags & ZEND_ACC_ABSTRACT))
+		 && intern->ignore_visibility == 0)
 	{
 		if (mptr->common.fn_flags & ZEND_ACC_ABSTRACT) {
 			zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
@@ -2959,6 +2961,27 @@
 }
 /* }}} */

+/* {{{ proto public void ReflectionMethod::setAccessible()
+   Sets whether non-public methods can be invoked */
+ZEND_METHOD(reflection_method, setAccessible)
+{
+	reflection_object *intern;
+	zend_bool visible;
+
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &visible) == FAILURE) {
+		return;
+	}
+
+	intern = (reflection_object *) zend_object_store_get_object(getThis() TSRMLS_CC);
+
+	if (intern == NULL) {
+		return;
+	}
+
+	intern->ignore_visibility = visible;
+}
+/* }}} */
+
 /* {{{ proto public static mixed ReflectionClass::export(mixed argument [, bool return]) throws ReflectionException
    Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
 ZEND_METHOD(reflection_class, export)
@@ -4375,10 +4398,10 @@
 		reference->prop = *property_info;
 	}
 	reference->ce = ce;
-	reference->ignore_visibility = 0;
 	intern->ptr = reference;
 	intern->ref_type = REF_TYPE_PROPERTY;
 	intern->ce = ce;
+	intern->ignore_visibility = 0;
 }
 /* }}} */

@@ -4491,7 +4514,7 @@
 	METHOD_NOTSTATIC(reflection_property_ptr);
 	GET_REFLECTION_OBJECT_PTR(ref);

-	if (!(ref->prop.flags & (ZEND_ACC_PUBLIC | ZEND_ACC_IMPLICIT_PUBLIC)) && ref->ignore_visibility == 0) {
+	if (!(ref->prop.flags & (ZEND_ACC_PUBLIC | ZEND_ACC_IMPLICIT_PUBLIC)) && intern->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));
@@ -4543,7 +4566,7 @@
 	METHOD_NOTSTATIC(reflection_property_ptr);
 	GET_REFLECTION_OBJECT_PTR(ref);

-	if (!(ref->prop.flags & ZEND_ACC_PUBLIC) && ref->ignore_visibility == 0) {
+	if (!(ref->prop.flags & ZEND_ACC_PUBLIC) && intern->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));
@@ -4660,14 +4683,19 @@
 ZEND_METHOD(reflection_property, setAccessible)
 {
 	reflection_object *intern;
-	property_reference *ref;
 	zend_bool visible;

 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &visible) == FAILURE) {
 		return;
 	}
-	GET_REFLECTION_OBJECT_PTR(ref);
-	ref->ignore_visibility = visible;
+
+	intern = (reflection_object *) zend_object_store_get_object(getThis() TSRMLS_CC);
+
+	if (intern == NULL) {
+		return;
+	}
+
+	intern->ignore_visibility = visible;
 }
 /* }}} */

@@ -5095,6 +5123,10 @@
 	ZEND_ARG_ARRAY_INFO(0, args, 0)
 ZEND_END_ARG_INFO()

+ZEND_BEGIN_ARG_INFO(arginfo_reflection_method_setAccessible, 0)
+	ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO()
+
 static const zend_function_entry reflection_method_functions[] = {
 	ZEND_ME(reflection_method, export, arginfo_reflection_method_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
 	ZEND_ME(reflection_method, __construct, arginfo_reflection_method___construct, 0)
@@ -5112,6 +5144,7 @@
 	ZEND_ME(reflection_method, invokeArgs, arginfo_reflection_method_invokeArgs, 0)
 	ZEND_ME(reflection_method, getDeclaringClass, NULL, 0)
 	ZEND_ME(reflection_method, getPrototype, NULL, 0)
+	ZEND_ME(reflection_property, setAccessible, arginfo_reflection_method_setAccessible, 0)
 	{NULL, NULL, NULL}
 };


Copied: php/php-src/branches/PHP_5_3/ext/reflection/tests/ReflectionMethod_setAccessible.phpt (from rev 288379, php/php-src/trunk/ext/reflection/tests/ReflectionMethod_setAccessible.phpt)
===================================================================
--- php/php-src/branches/PHP_5_3/ext/reflection/tests/ReflectionMethod_setAccessible.phpt	                        (rev 0)
+++ php/php-src/branches/PHP_5_3/ext/reflection/tests/ReflectionMethod_setAccessible.phpt	2009-09-16 17:24:46 UTC (rev 288380)
@@ -0,0 +1,111 @@
+--TEST--
+Test ReflectionMethod::setAccessible().
+--FILE--
+<?php
+class A {
+    private function aPrivate($a) { print __METHOD__ . "\n"; }
+    private static function aPrivateStatic($a) { print __METHOD__ . "\n"; }
+    protected function aProtected($a) { print __METHOD__ . "\n"; }
+    protected static function aProtectedStatic($a) { print __METHOD__ . "\n"; }
+}
+
+$private         = new ReflectionMethod('A', 'aPrivate');
+$privateStatic   = new ReflectionMethod('A', 'aPrivateStatic');
+$protected       = new ReflectionMethod('A', 'aProtected');
+$protectedStatic = new ReflectionMethod('A', 'aProtectedStatic');
+
+try {
+    $private->invoke(new A, NULL);
+}
+
+catch (ReflectionException $e) {
+    var_dump($e->getMessage());
+}
+
+try {
+    $private->invokeArgs(new A, array(NULL));
+}
+
+catch (ReflectionException $e) {
+    var_dump($e->getMessage());
+}
+
+try {
+    $privateStatic->invoke(NULL, NULL);
+}
+
+catch (ReflectionException $e) {
+    var_dump($e->getMessage());
+}
+
+try {
+    $privateStatic->invokeArgs(NULL, array(NULL));
+}
+
+catch (ReflectionException $e) {
+    var_dump($e->getMessage());
+}
+
+try {
+    $protected->invoke(new A, NULL);
+}
+
+catch (ReflectionException $e) {
+    var_dump($e->getMessage());
+}
+
+try {
+    $protected->invokeArgs(new A, array(NULL));
+}
+
+catch (ReflectionException $e) {
+    var_dump($e->getMessage());
+}
+
+try {
+    $protectedStatic->invoke(NULL, NULL);
+}
+
+catch (ReflectionException $e) {
+    var_dump($e->getMessage());
+}
+
+try {
+    $protectedStatic->invokeArgs(NULL, array(NULL));
+}
+
+catch (ReflectionException $e) {
+    var_dump($e->getMessage());
+}
+
+$private->setAccessible(TRUE);
+$privateStatic->setAccessible(TRUE);
+$protected->setAccessible(TRUE);
+$protectedStatic->setAccessible(TRUE);
+
+$private->invoke(new A, NULL);
+$private->invokeArgs(new A, array(NULL));
+$privateStatic->invoke(NULL, NULL);
+$privateStatic->invokeArgs(NULL, array(NULL));
+$protected->invoke(new A, NULL);
+$protected->invokeArgs(new A, array(NULL));
+$protectedStatic->invoke(NULL, NULL);
+$protectedStatic->invokeArgs(NULL, array(NULL));
+?>
+--EXPECT--
+string(73) "Trying to invoke private method A::aPrivate() from scope ReflectionMethod"
+string(73) "Trying to invoke private method A::aPrivate() from scope ReflectionMethod"
+string(79) "Trying to invoke private method A::aPrivateStatic() from scope ReflectionMethod"
+string(79) "Trying to invoke private method A::aPrivateStatic() from scope ReflectionMethod"
+string(77) "Trying to invoke protected method A::aProtected() from scope ReflectionMethod"
+string(77) "Trying to invoke protected method A::aProtected() from scope ReflectionMethod"
+string(83) "Trying to invoke protected method A::aProtectedStatic() from scope ReflectionMethod"
+string(83) "Trying to invoke protected method A::aProtectedStatic() from scope ReflectionMethod"
+A::aPrivate
+A::aPrivate
+A::aPrivateStatic
+A::aPrivateStatic
+A::aProtected
+A::aProtected
+A::aProtectedStatic
+A::aProtectedStatic

Modified: php/php-src/trunk/NEWS
===================================================================
--- php/php-src/trunk/NEWS	2009-09-16 17:03:44 UTC (rev 288379)
+++ php/php-src/trunk/NEWS	2009-09-16 17:24:46 UTC (rev 288380)
@@ -45,8 +45,6 @@
   (Sara)
 - Added stream_resolve_include_path() function which checks which file fopen()
   with a relative path will open. (Sara)
-- Added ReflectionMethod::setAccessible() for invoking non-public methods
-  through the Reflection API. (Sebastian)

 - Fixed bug #46647 (SplFileObject::fgetcsv segfaults). (Etienne)
 - Fixed bug #40325 (Vary: header missing in gzip output handlers). (Mike)
-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to