diff options
author | Remi Collet <remi@php.net> | 2013-12-10 16:07:16 +0100 |
---|---|---|
committer | Remi Collet <remi@php.net> | 2013-12-10 16:07:16 +0100 |
commit | 3e963f8eb44863ef3d758eabe791190b0fd7bb9a (patch) | |
tree | ed018479c9c958c7971c478b81dbc061096a7fbd /ext/reflection | |
parent | c062c18d426e8b1e4d7e4fabb6a5eae331f6e58b (diff) | |
download | php-git-3e963f8eb44863ef3d758eabe791190b0fd7bb9a.tar.gz |
Fixed Bug #66218 zend_register_functions breaks reflection
Functions registered using zend_register_functions instead of zend_module_entry.functions are not seen on reflection.
Ex: additional_functions from api_module_entry.
Ex: in CLI, dl, cli_set_process_title and cli_get_process_title
Note:
- also affects functions overrided in extension
(should be be reported in extension, where overrided, not in original extension)
- also allow extension to call zend_register_functions for various list
(instead of having a single bug list)
Diffstat (limited to 'ext/reflection')
-rw-r--r-- | ext/reflection/php_reflection.c | 66 | ||||
-rw-r--r-- | ext/reflection/tests/ReflectionExtension_bug66218.phpt | 21 |
2 files changed, 47 insertions, 40 deletions
diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index c4a7c554f0..803b12b031 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -1105,29 +1105,26 @@ static void _extension_string(string *str, zend_module_entry *module, char *inde string_free(&str_constants); } - if (module->functions && module->functions->fname) { + { + HashPosition iterator; zend_function *fptr; - const zend_function_entry *func = module->functions; - - string_printf(str, "\n - Functions {\n"); - - /* Is there a better way of doing this? */ - while (func->fname) { - int fname_len = strlen(func->fname); - char *lc_name = zend_str_tolower_dup(func->fname, fname_len); - - if (zend_hash_find(EG(function_table), lc_name, fname_len + 1, (void**) &fptr) == FAILURE) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Internal error: Cannot find extension function %s in global function table", func->fname); - func++; - efree(lc_name); - continue; + int first = 1; + + zend_hash_internal_pointer_reset_ex(CG(function_table), &iterator); + while (zend_hash_get_current_data_ex(CG(function_table), (void **) &fptr, &iterator) == SUCCESS) { + if (fptr->common.type==ZEND_INTERNAL_FUNCTION + && fptr->internal_function.module == module) { + if (first) { + string_printf(str, "\n - Functions {\n"); + first = 0; + } + _function_string(str, fptr, NULL, " " TSRMLS_CC); } - - _function_string(str, fptr, NULL, " " TSRMLS_CC); - efree(lc_name); - func++; + zend_hash_move_forward_ex(CG(function_table), &iterator); + } + if (!first) { + string_printf(str, "%s }\n", indent); } - string_printf(str, "%s }\n", indent); } { @@ -5242,6 +5239,9 @@ ZEND_METHOD(reflection_extension, getFunctions) { reflection_object *intern; zend_module_entry *module; + HashPosition iterator; + zval *function; + zend_function *fptr; if (zend_parse_parameters_none() == FAILURE) { return; @@ -5249,29 +5249,15 @@ ZEND_METHOD(reflection_extension, getFunctions) GET_REFLECTION_OBJECT_PTR(module); array_init(return_value); - if (module->functions) { - zval *function; - zend_function *fptr; - const zend_function_entry *func = module->functions; - - /* Is there a better way of doing this? */ - while (func->fname) { - int fname_len = strlen(func->fname); - char *lc_name = zend_str_tolower_dup(func->fname, fname_len); - - if (zend_hash_find(EG(function_table), lc_name, fname_len + 1, (void**) &fptr) == FAILURE) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Internal error: Cannot find extension function %s in global function table", func->fname); - func++; - efree(lc_name); - continue; - } - + zend_hash_internal_pointer_reset_ex(CG(function_table), &iterator); + while (zend_hash_get_current_data_ex(CG(function_table), (void **) &fptr, &iterator) == SUCCESS) { + if (fptr->common.type==ZEND_INTERNAL_FUNCTION + && fptr->internal_function.module == module) { ALLOC_ZVAL(function); reflection_function_factory(fptr, NULL, function TSRMLS_CC); - add_assoc_zval_ex(return_value, func->fname, fname_len+1, function); - func++; - efree(lc_name); + add_assoc_zval(return_value, fptr->common.function_name, function); } + zend_hash_move_forward_ex(CG(function_table), &iterator); } } /* }}} */ diff --git a/ext/reflection/tests/ReflectionExtension_bug66218.phpt b/ext/reflection/tests/ReflectionExtension_bug66218.phpt new file mode 100644 index 0000000000..e263624bad --- /dev/null +++ b/ext/reflection/tests/ReflectionExtension_bug66218.phpt @@ -0,0 +1,21 @@ +--TEST-- +ReflectionExtension::getFunctions() ##6218 zend_register_functions breaks reflection +--SKIPIF-- +<?php +if (!extension_loaded('reflection')) print 'skip missing reflection extension'; +if (PHP_SAPI != "cli") die("skip CLI only test"); +if (!function_exists("dl")) die("skip need dl"); +?> +--FILE-- +<?php +$r = new ReflectionExtension('standard'); +$t = $r->getFunctions(); +var_dump($t['dl']); +?> +Done +--EXPECTF-- +object(ReflectionFunction)#%d (1) { + ["name"]=> + string(2) "dl" +} +Done |