felipe                                   Fri, 11 Jun 2010 23:37:55 +0000

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

Log:
- Fixed bug #52057 (ReflectionClass fails on Closure class)

Bug: http://bugs.php.net/52057 (Closed) ReflectionClass fails on Closure class
      
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/bug52057.phpt
    U   php/php-src/trunk/ext/reflection/php_reflection.c
    A   php/php-src/trunk/ext/reflection/tests/bug52057.phpt

Modified: php/php-src/branches/PHP_5_3/NEWS
===================================================================
--- php/php-src/branches/PHP_5_3/NEWS   2010-06-11 23:20:13 UTC (rev 300392)
+++ php/php-src/branches/PHP_5_3/NEWS   2010-06-11 23:37:55 UTC (rev 300393)
@@ -73,6 +73,7 @@

 - Fixed bug #52060 (Memory leak when passing a closure to method_exists()).
   (Felipe)
+- Fixed bug #52057 (ReflectionClass fails on Closure class). (Felipe)
 - Fixed bug #52019 (make lcov doesn't support TESTS variable anymore). 
(Patrick)
 - Fixed bug #52010 (open_basedir restrictions mismatch on vacuum command).
   (Ilia)

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        
2010-06-11 23:20:13 UTC (rev 300392)
+++ php/php-src/branches/PHP_5_3/ext/reflection/php_reflection.c        
2010-06-11 23:37:55 UTC (rev 300393)
@@ -3384,7 +3384,9 @@

        GET_REFLECTION_OBJECT_PTR(ce);
        lc_name = zend_str_tolower_dup(name, name_len);
-       if (zend_hash_exists(&ce->function_table, lc_name, name_len + 1)) {
+       if ((ce == zend_ce_closure && (name_len == 
sizeof(ZEND_INVOKE_FUNC_NAME)-1)
+               && memcmp(lc_name, ZEND_INVOKE_FUNC_NAME, 
sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0)
+               || zend_hash_exists(&ce->function_table, lc_name, name_len + 
1)) {
                efree(lc_name);
                RETURN_TRUE;
        } else {
@@ -3401,6 +3403,7 @@
        reflection_object *intern;
        zend_class_entry *ce;
        zend_function *mptr;
+       zval obj_tmp;
        char *name, *lc_name;
        int name_len;

@@ -3419,6 +3422,14 @@
                   method and not the closure definition itself */
                reflection_method_factory(ce, mptr, NULL, return_value 
TSRMLS_CC);
                efree(lc_name);
+       } else if (ce == zend_ce_closure && !intern->obj && (name_len == 
sizeof(ZEND_INVOKE_FUNC_NAME)-1)
+               && memcmp(lc_name, ZEND_INVOKE_FUNC_NAME, 
sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
+               && object_init_ex(&obj_tmp, ce) == SUCCESS && (mptr = 
zend_get_closure_invoke_method(&obj_tmp TSRMLS_CC)) != NULL) {
+               /* don't assign closure_object since we only reflect the invoke 
handler
+                  method and not the closure definition itself */
+               reflection_method_factory(ce, mptr, NULL, return_value 
TSRMLS_CC);
+               zval_dtor(&obj_tmp);
+               efree(lc_name);
        } else if (zend_hash_find(&ce->function_table, lc_name, name_len + 1, 
(void**) &mptr) == SUCCESS) {
                reflection_method_factory(ce, mptr, NULL, return_value 
TSRMLS_CC);
                efree(lc_name);

Added: php/php-src/branches/PHP_5_3/ext/reflection/tests/bug52057.phpt
===================================================================
--- php/php-src/branches/PHP_5_3/ext/reflection/tests/bug52057.phpt             
                (rev 0)
+++ php/php-src/branches/PHP_5_3/ext/reflection/tests/bug52057.phpt     
2010-06-11 23:37:55 UTC (rev 300393)
@@ -0,0 +1,54 @@
+--TEST--
+Bug #52057 (ReflectionClass fails on Closure class)
+--FILE--
+<?php
+
+$closure = function($a) { echo $a; };
+
+$reflection = new ReflectionClass('closure');
+var_dump($reflection->hasMethod('__invoke')); // true
+
+$reflection = new ReflectionClass($closure);
+var_dump($reflection->hasMethod('__invoke')); // true
+
+$reflection = new ReflectionObject($closure);
+var_dump($reflection->hasMethod('__invoke')); // true
+
+$reflection = new ReflectionClass('closure');
+var_dump($h = $reflection->getMethod('__invoke')); // true
+var_dump($h->class.'::'.$h->getName());
+
+$reflection = new ReflectionClass($closure);
+var_dump($h = $reflection->getMethod('__invoke')); // true
+var_dump($h->class.'::'.$h->getName());
+
+$reflection = new ReflectionObject($closure);
+var_dump($h = $reflection->getMethod('__invoke')); // true
+var_dump($h->class.'::'.$h->getName());
+
+?>
+--EXPECTF--
+bool(true)
+bool(true)
+bool(true)
+object(ReflectionMethod)#%d (2) {
+  ["name"]=>
+  string(8) "__invoke"
+  ["class"]=>
+  string(7) "Closure"
+}
+string(17) "Closure::__invoke"
+object(ReflectionMethod)#%d (2) {
+  ["name"]=>
+  string(8) "__invoke"
+  ["class"]=>
+  string(7) "Closure"
+}
+string(17) "Closure::__invoke"
+object(ReflectionMethod)#%d (2) {
+  ["name"]=>
+  string(8) "__invoke"
+  ["class"]=>
+  string(7) "Closure"
+}
+string(17) "Closure::__invoke"


Property changes on: 
php/php-src/branches/PHP_5_3/ext/reflection/tests/bug52057.phpt
___________________________________________________________________
Added: svn:keywords
   + Id Rev Revision
Added: svn:eol-style
   + native

Modified: php/php-src/trunk/ext/reflection/php_reflection.c
===================================================================
--- php/php-src/trunk/ext/reflection/php_reflection.c   2010-06-11 23:20:13 UTC 
(rev 300392)
+++ php/php-src/trunk/ext/reflection/php_reflection.c   2010-06-11 23:37:55 UTC 
(rev 300393)
@@ -3588,7 +3588,9 @@

        GET_REFLECTION_OBJECT_PTR(ce);
        lc_name = zend_str_tolower_dup(name, name_len);
-       if (zend_hash_exists(&ce->function_table, lc_name, name_len + 1)) {
+       if ((ce == zend_ce_closure && (name_len == 
sizeof(ZEND_INVOKE_FUNC_NAME)-1)
+               && memcmp(lc_name, ZEND_INVOKE_FUNC_NAME, 
sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0)
+               || zend_hash_exists(&ce->function_table, lc_name, name_len + 
1)) {
                efree(lc_name);
                RETURN_TRUE;
        } else {
@@ -3605,6 +3607,7 @@
        reflection_object *intern;
        zend_class_entry *ce;
        zend_function *mptr;
+       zval obj_tmp;
        char *name, *lc_name;
        int name_len;

@@ -3623,6 +3626,14 @@
                   method and not the closure definition itself */
                reflection_method_factory(ce, mptr, NULL, return_value 
TSRMLS_CC);
                efree(lc_name);
+       } else if (ce == zend_ce_closure && !intern->obj && (name_len == 
sizeof(ZEND_INVOKE_FUNC_NAME)-1)
+               && memcmp(lc_name, ZEND_INVOKE_FUNC_NAME, 
sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
+               && object_init_ex(&obj_tmp, ce) == SUCCESS && (mptr = 
zend_get_closure_invoke_method(&obj_tmp TSRMLS_CC)) != NULL) {
+               /* don't assign closure_object since we only reflect the invoke 
handler
+                  method and not the closure definition itself */
+               reflection_method_factory(ce, mptr, NULL, return_value 
TSRMLS_CC);
+               zval_dtor(&obj_tmp);
+               efree(lc_name);
        } else if (zend_hash_find(&ce->function_table, lc_name, name_len + 1, 
(void**) &mptr) == SUCCESS) {
                reflection_method_factory(ce, mptr, NULL, return_value 
TSRMLS_CC);
                efree(lc_name);

Added: php/php-src/trunk/ext/reflection/tests/bug52057.phpt
===================================================================
--- php/php-src/trunk/ext/reflection/tests/bug52057.phpt                        
        (rev 0)
+++ php/php-src/trunk/ext/reflection/tests/bug52057.phpt        2010-06-11 
23:37:55 UTC (rev 300393)
@@ -0,0 +1,54 @@
+--TEST--
+Bug #52057 (ReflectionClass fails on Closure class)
+--FILE--
+<?php
+
+$closure = function($a) { echo $a; };
+
+$reflection = new ReflectionClass('closure');
+var_dump($reflection->hasMethod('__invoke')); // true
+
+$reflection = new ReflectionClass($closure);
+var_dump($reflection->hasMethod('__invoke')); // true
+
+$reflection = new ReflectionObject($closure);
+var_dump($reflection->hasMethod('__invoke')); // true
+
+$reflection = new ReflectionClass('closure');
+var_dump($h = $reflection->getMethod('__invoke')); // true
+var_dump($h->class.'::'.$h->getName());
+
+$reflection = new ReflectionClass($closure);
+var_dump($h = $reflection->getMethod('__invoke')); // true
+var_dump($h->class.'::'.$h->getName());
+
+$reflection = new ReflectionObject($closure);
+var_dump($h = $reflection->getMethod('__invoke')); // true
+var_dump($h->class.'::'.$h->getName());
+
+?>
+--EXPECTF--
+bool(true)
+bool(true)
+bool(true)
+object(ReflectionMethod)#%d (2) {
+  ["name"]=>
+  string(8) "__invoke"
+  ["class"]=>
+  string(7) "Closure"
+}
+string(17) "Closure::__invoke"
+object(ReflectionMethod)#%d (2) {
+  ["name"]=>
+  string(8) "__invoke"
+  ["class"]=>
+  string(7) "Closure"
+}
+string(17) "Closure::__invoke"
+object(ReflectionMethod)#%d (2) {
+  ["name"]=>
+  string(8) "__invoke"
+  ["class"]=>
+  string(7) "Closure"
+}
+string(17) "Closure::__invoke"


Property changes on: php/php-src/trunk/ext/reflection/tests/bug52057.phpt
___________________________________________________________________
Added: svn:keywords
   + Id Rev Revision
Added: svn:eol-style
   + native

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to