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