Changes zend_is_callable() to use zend_string* instead of char*

This commit is contained in:
Dmitry Stogov 2014-02-25 16:03:34 +04:00
parent b965647e44
commit 639e4e1afa
11 changed files with 97 additions and 108 deletions

View file

@ -2880,7 +2880,7 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca
ftable = &fcc->calling_scope->function_table; ftable = &fcc->calling_scope->function_table;
if (ce_org && !instanceof_function(ce_org, fcc->calling_scope TSRMLS_CC)) { if (ce_org && !instanceof_function(ce_org, fcc->calling_scope TSRMLS_CC)) {
if (error) zend_spprintf(error, 0, "class '%s' is not a subclass of '%s'", ce_org->name, fcc->calling_scope->name); if (error) zend_spprintf(error, 0, "class '%s' is not a subclass of '%s'", ce_org->name->val, fcc->calling_scope->name->val);
return 0; return 0;
} }
mname = STR_INIT(Z_STRVAL_P(callable) + clen + 2, mlen, 0); mname = STR_INIT(Z_STRVAL_P(callable) + clen + 2, mlen, 0);
@ -3080,18 +3080,14 @@ get_function_via_handler:
} }
/* }}} */ /* }}} */
ZEND_API zend_bool zend_is_callable_ex(zval *callable, zval *object_ptr, uint check_flags, char **callable_name, int *callable_name_len, zend_fcall_info_cache *fcc, char **error TSRMLS_DC) /* {{{ */ ZEND_API zend_bool zend_is_callable_ex(zval *callable, zval *object_ptr, uint check_flags, zend_string **callable_name, zend_fcall_info_cache *fcc, char **error TSRMLS_DC) /* {{{ */
{ {
zend_bool ret; zend_bool ret;
int callable_name_len_local;
zend_fcall_info_cache fcc_local; zend_fcall_info_cache fcc_local;
if (callable_name) { if (callable_name) {
*callable_name = NULL; *callable_name = NULL;
} }
if (callable_name_len == NULL) {
callable_name_len = &callable_name_len_local;
}
if (fcc == NULL) { if (fcc == NULL) {
fcc = &fcc_local; fcc = &fcc_local;
} }
@ -3124,17 +3120,16 @@ ZEND_API zend_bool zend_is_callable_ex(zval *callable, zval *object_ptr, uint ch
if (callable_name) { if (callable_name) {
char *ptr; char *ptr;
*callable_name_len = fcc->calling_scope->name->len + Z_STRLEN_P(callable) + sizeof("::") - 1; *callable_name = STR_ALLOC(fcc->calling_scope->name->len + Z_STRLEN_P(callable) + sizeof("::") - 1, 0);
ptr = *callable_name = emalloc(*callable_name_len + 1); ptr = (*callable_name)->val;
memcpy(ptr, fcc->calling_scope->name, fcc->calling_scope->name->len); memcpy(ptr, fcc->calling_scope->name->val, fcc->calling_scope->name->len);
ptr += fcc->calling_scope->name->len; ptr += fcc->calling_scope->name->len;
memcpy(ptr, "::", sizeof("::") - 1); memcpy(ptr, "::", sizeof("::") - 1);
ptr += sizeof("::") - 1; ptr += sizeof("::") - 1;
memcpy(ptr, Z_STRVAL_P(callable), Z_STRLEN_P(callable) + 1); memcpy(ptr, Z_STRVAL_P(callable), Z_STRLEN_P(callable) + 1);
} }
} else if (callable_name) { } else if (callable_name) {
*callable_name = estrndup(Z_STRVAL_P(callable), Z_STRLEN_P(callable)); *callable_name = STR_COPY(Z_STR_P(callable));
*callable_name_len = Z_STRLEN_P(callable);
} }
if (check_flags & IS_CALLABLE_CHECK_SYNTAX_ONLY) { if (check_flags & IS_CALLABLE_CHECK_SYNTAX_ONLY) {
fcc->called_scope = fcc->calling_scope; fcc->called_scope = fcc->calling_scope;
@ -3174,8 +3169,9 @@ ZEND_API zend_bool zend_is_callable_ex(zval *callable, zval *object_ptr, uint ch
if (callable_name) { if (callable_name) {
char *ptr; char *ptr;
*callable_name_len = Z_STRLEN_P(obj) + Z_STRLEN_P(method) + sizeof("::") - 1;
ptr = *callable_name = emalloc(*callable_name_len + 1); *callable_name = STR_ALLOC(Z_STRLEN_P(obj) + Z_STRLEN_P(method) + sizeof("::") - 1, 0);
ptr = (*callable_name)->val;
memcpy(ptr, Z_STRVAL_P(obj), Z_STRLEN_P(obj)); memcpy(ptr, Z_STRVAL_P(obj), Z_STRLEN_P(obj));
ptr += Z_STRLEN_P(obj); ptr += Z_STRLEN_P(obj);
memcpy(ptr, "::", sizeof("::") - 1); memcpy(ptr, "::", sizeof("::") - 1);
@ -3204,9 +3200,9 @@ ZEND_API zend_bool zend_is_callable_ex(zval *callable, zval *object_ptr, uint ch
if (callable_name) { if (callable_name) {
char *ptr; char *ptr;
*callable_name_len = fcc->calling_scope->name->len + Z_STRLEN_P(method) + sizeof("::") - 1; *callable_name = STR_ALLOC(fcc->calling_scope->name->len + Z_STRLEN_P(method) + sizeof("::") - 1, 0);
ptr = *callable_name = emalloc(*callable_name_len + 1); ptr = (*callable_name)->val;
memcpy(ptr, fcc->calling_scope->name, fcc->calling_scope->name->len); memcpy(ptr, fcc->calling_scope->name->val, fcc->calling_scope->name->len);
ptr += fcc->calling_scope->name->len; ptr += fcc->calling_scope->name->len;
memcpy(ptr, "::", sizeof("::") - 1); memcpy(ptr, "::", sizeof("::") - 1);
ptr += sizeof("::") - 1; ptr += sizeof("::") - 1;
@ -3244,8 +3240,7 @@ ZEND_API zend_bool zend_is_callable_ex(zval *callable, zval *object_ptr, uint ch
if (error) zend_spprintf(error, 0, "array must have exactly two members"); if (error) zend_spprintf(error, 0, "array must have exactly two members");
} }
if (callable_name) { if (callable_name) {
*callable_name = estrndup("Array", sizeof("Array")-1); *callable_name = STR_INIT("Array", sizeof("Array")-1, 0);
*callable_name_len = sizeof("Array") - 1;
} }
} }
} }
@ -3257,10 +3252,9 @@ ZEND_API zend_bool zend_is_callable_ex(zval *callable, zval *object_ptr, uint ch
if (callable_name) { if (callable_name) {
zend_class_entry *ce = Z_OBJCE_P(callable); /* TBFixed: what if it's overloaded? */ zend_class_entry *ce = Z_OBJCE_P(callable); /* TBFixed: what if it's overloaded? */
*callable_name_len = ce->name->len + sizeof("::__invoke") - 1; *callable_name = STR_ALLOC(ce->name->len + sizeof("::__invoke") - 1, 0);
*callable_name = emalloc(*callable_name_len + 1); memcpy((*callable_name)->val, ce->name->val, ce->name->len);
memcpy(*callable_name, ce->name, ce->name->len); memcpy((*callable_name)->val + ce->name->len, "::__invoke", sizeof("::__invoke"));
memcpy((*callable_name) + ce->name->len, "::__invoke", sizeof("::__invoke"));
} }
return 1; return 1;
} }
@ -3272,8 +3266,7 @@ ZEND_API zend_bool zend_is_callable_ex(zval *callable, zval *object_ptr, uint ch
int use_copy; int use_copy;
zend_make_printable_zval(callable, &expr_copy, &use_copy); zend_make_printable_zval(callable, &expr_copy, &use_copy);
*callable_name = estrndup(Z_STRVAL(expr_copy), Z_STRLEN(expr_copy)); *callable_name = STR_COPY(Z_STR(expr_copy));
*callable_name_len = Z_STRLEN(expr_copy);
zval_dtor(&expr_copy); zval_dtor(&expr_copy);
} }
if (error) zend_spprintf(error, 0, "no array or string given"); if (error) zend_spprintf(error, 0, "no array or string given");
@ -3282,17 +3275,17 @@ ZEND_API zend_bool zend_is_callable_ex(zval *callable, zval *object_ptr, uint ch
} }
/* }}} */ /* }}} */
ZEND_API zend_bool zend_is_callable(zval *callable, uint check_flags, char **callable_name TSRMLS_DC) /* {{{ */ ZEND_API zend_bool zend_is_callable(zval *callable, uint check_flags, zend_string **callable_name TSRMLS_DC) /* {{{ */
{ {
return zend_is_callable_ex(callable, NULL, check_flags, callable_name, NULL, NULL, NULL TSRMLS_CC); return zend_is_callable_ex(callable, NULL, check_flags, callable_name, NULL, NULL TSRMLS_CC);
} }
/* }}} */ /* }}} */
ZEND_API zend_bool zend_make_callable(zval *callable, char **callable_name TSRMLS_DC) /* {{{ */ ZEND_API zend_bool zend_make_callable(zval *callable, zend_string **callable_name TSRMLS_DC) /* {{{ */
{ {
zend_fcall_info_cache fcc; zend_fcall_info_cache fcc;
if (zend_is_callable_ex(callable, NULL, IS_CALLABLE_STRICT, callable_name, NULL, &fcc, NULL TSRMLS_CC)) { if (zend_is_callable_ex(callable, NULL, IS_CALLABLE_STRICT, callable_name, &fcc, NULL TSRMLS_CC)) {
if (Z_TYPE_P(callable) == IS_STRING && fcc.calling_scope) { if (Z_TYPE_P(callable) == IS_STRING && fcc.calling_scope) {
zval_dtor(callable); zval_dtor(callable);
array_init(callable); array_init(callable);
@ -3315,9 +3308,9 @@ ZEND_API zend_bool zend_make_callable(zval *callable, char **callable_name TSRML
} }
/* }}} */ /* }}} */
ZEND_API int zend_fcall_info_init(zval *callable, uint check_flags, zend_fcall_info *fci, zend_fcall_info_cache *fcc, char **callable_name, char **error TSRMLS_DC) /* {{{ */ ZEND_API int zend_fcall_info_init(zval *callable, uint check_flags, zend_fcall_info *fci, zend_fcall_info_cache *fcc, zend_string **callable_name, char **error TSRMLS_DC) /* {{{ */
{ {
if (!zend_is_callable_ex(callable, NULL, check_flags, callable_name, NULL, fcc, error TSRMLS_CC)) { if (!zend_is_callable_ex(callable, NULL, check_flags, callable_name, fcc, error TSRMLS_CC)) {
return FAILURE; return FAILURE;
} }

View file

@ -295,9 +295,9 @@ ZEND_API void zend_wrong_param_count(TSRMLS_D);
#define IS_CALLABLE_STRICT (IS_CALLABLE_CHECK_IS_STATIC) #define IS_CALLABLE_STRICT (IS_CALLABLE_CHECK_IS_STATIC)
ZEND_API zend_bool zend_is_callable_ex(zval *callable, zval *object_ptr, uint check_flags, char **callable_name, int *callable_name_len, zend_fcall_info_cache *fcc, char **error TSRMLS_DC); ZEND_API zend_bool zend_is_callable_ex(zval *callable, zval *object_ptr, uint check_flags, zend_string **callable_name, zend_fcall_info_cache *fcc, char **error TSRMLS_DC);
ZEND_API zend_bool zend_is_callable(zval *callable, uint check_flags, char **callable_name TSRMLS_DC); ZEND_API zend_bool zend_is_callable(zval *callable, uint check_flags, zend_string **callable_name TSRMLS_DC);
ZEND_API zend_bool zend_make_callable(zval *callable, char **callable_name TSRMLS_DC); ZEND_API zend_bool zend_make_callable(zval *callable, zend_string **callable_name TSRMLS_DC);
ZEND_API const char *zend_get_module_version(const char *module_name); ZEND_API const char *zend_get_module_version(const char *module_name);
ZEND_API int zend_get_module_started(const char *module_name); ZEND_API int zend_get_module_started(const char *module_name);
ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, zval *property, int access_type, zend_string *doc_comment TSRMLS_DC); ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, zval *property, int access_type, zend_string *doc_comment TSRMLS_DC);
@ -467,7 +467,7 @@ ZEND_API extern const zend_fcall_info_cache empty_fcall_info_cache;
* The callable_name argument may be NULL. * The callable_name argument may be NULL.
* Set check_flags to IS_CALLABLE_STRICT for every new usage! * Set check_flags to IS_CALLABLE_STRICT for every new usage!
*/ */
ZEND_API int zend_fcall_info_init(zval *callable, uint check_flags, zend_fcall_info *fci, zend_fcall_info_cache *fcc, char **callable_name, char **error TSRMLS_DC); ZEND_API int zend_fcall_info_init(zval *callable, uint check_flags, zend_fcall_info *fci, zend_fcall_info_cache *fcc, zend_string **callable_name, char **error TSRMLS_DC);
/** Clear arguments connected with zend_fcall_info *fci /** Clear arguments connected with zend_fcall_info *fci
* If free_mem is not zero then the params array gets free'd as well * If free_mem is not zero then the params array gets free'd as well

View file

@ -1469,7 +1469,7 @@ ZEND_FUNCTION(trigger_error)
ZEND_FUNCTION(set_error_handler) ZEND_FUNCTION(set_error_handler)
{ {
zval *error_handler; zval *error_handler;
char *error_handler_name = NULL; zend_string *error_handler_name = NULL;
long error_type = E_ALL; long error_type = E_ALL;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|l", &error_handler, &error_type) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|l", &error_handler, &error_type) == FAILURE) {
@ -1479,11 +1479,11 @@ ZEND_FUNCTION(set_error_handler)
if (Z_TYPE_P(error_handler) != IS_NULL) { /* NULL == unset */ if (Z_TYPE_P(error_handler) != IS_NULL) { /* NULL == unset */
if (!zend_is_callable(error_handler, 0, &error_handler_name TSRMLS_CC)) { if (!zend_is_callable(error_handler, 0, &error_handler_name TSRMLS_CC)) {
zend_error(E_WARNING, "%s() expects the argument (%s) to be a valid callback", zend_error(E_WARNING, "%s() expects the argument (%s) to be a valid callback",
get_active_function_name(TSRMLS_C), error_handler_name?error_handler_name:"unknown"); get_active_function_name(TSRMLS_C), error_handler_name?error_handler_name->val:"unknown");
efree(error_handler_name); STR_RELEASE(error_handler_name);
return; return;
} }
efree(error_handler_name); STR_RELEASE(error_handler_name);
} }
if (Z_TYPE(EG(user_error_handler)) != IS_UNDEF) { if (Z_TYPE(EG(user_error_handler)) != IS_UNDEF) {
@ -1536,7 +1536,7 @@ ZEND_FUNCTION(restore_error_handler)
ZEND_FUNCTION(set_exception_handler) ZEND_FUNCTION(set_exception_handler)
{ {
zval *exception_handler; zval *exception_handler;
char *exception_handler_name = NULL; zend_string *exception_handler_name = NULL;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &exception_handler) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &exception_handler) == FAILURE) {
return; return;
@ -1545,11 +1545,11 @@ ZEND_FUNCTION(set_exception_handler)
if (Z_TYPE_P(exception_handler) != IS_NULL) { /* NULL == unset */ if (Z_TYPE_P(exception_handler) != IS_NULL) { /* NULL == unset */
if (!zend_is_callable(exception_handler, 0, &exception_handler_name TSRMLS_CC)) { if (!zend_is_callable(exception_handler, 0, &exception_handler_name TSRMLS_CC)) {
zend_error(E_WARNING, "%s() expects the argument (%s) to be a valid callback", zend_error(E_WARNING, "%s() expects the argument (%s) to be a valid callback",
get_active_function_name(TSRMLS_C), exception_handler_name?exception_handler_name:"unknown"); get_active_function_name(TSRMLS_C), exception_handler_name?exception_handler_name->val:"unknown");
efree(exception_handler_name); STR_RELEASE(exception_handler_name);
return; return;
} }
efree(exception_handler_name); STR_RELEASE(exception_handler_name);
} }
if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) { if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) {

View file

@ -777,20 +777,20 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
} }
if (!fci_cache || !fci_cache->initialized) { if (!fci_cache || !fci_cache->initialized) {
char *callable_name; zend_string *callable_name;
char *error = NULL; char *error = NULL;
if (!fci_cache) { if (!fci_cache) {
fci_cache = &fci_cache_local; fci_cache = &fci_cache_local;
} }
if (!zend_is_callable_ex(&fci->function_name, fci->object_ptr, IS_CALLABLE_CHECK_SILENT, &callable_name, NULL, fci_cache, &error TSRMLS_CC)) { if (!zend_is_callable_ex(&fci->function_name, fci->object_ptr, IS_CALLABLE_CHECK_SILENT, &callable_name, fci_cache, &error TSRMLS_CC)) {
if (error) { if (error) {
zend_error(E_WARNING, "Invalid callback %s, %s", callable_name, error); zend_error(E_WARNING, "Invalid callback %s, %s", callable_name->val, error);
efree(error); efree(error);
} }
if (callable_name) { if (callable_name) {
efree(callable_name); STR_RELEASE(callable_name);
} }
return FAILURE; return FAILURE;
} else if (error) { } else if (error) {
@ -801,7 +801,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
zend_error(E_STRICT, "%s", error); zend_error(E_STRICT, "%s", error);
efree(error); efree(error);
} }
efree(callable_name); STR_RELEASE(callable_name);
} }
EX(function_state).function = fci_cache->function_handler; EX(function_state).function = fci_cache->function_handler;

View file

@ -1320,7 +1320,7 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl
long limit = -1; long limit = -1;
zend_string *string_key; zend_string *string_key;
ulong num_key; ulong num_key;
char *callback_name; zend_string *callback_name;
int replace_count=0, old_replace_count; int replace_count=0, old_replace_count;
/* Get function parameters and do error-checking. */ /* Get function parameters and do error-checking. */
@ -1339,12 +1339,12 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl
} }
if (is_callable_replace) { if (is_callable_replace) {
if (!zend_is_callable(replace, 0, &callback_name TSRMLS_CC)) { if (!zend_is_callable(replace, 0, &callback_name TSRMLS_CC)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Requires argument 2, '%s', to be a valid callback", callback_name); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Requires argument 2, '%s', to be a valid callback", callback_name->val);
efree(callback_name); STR_RELEASE(callback_name);
ZVAL_DUP(return_value, subject); ZVAL_DUP(return_value, subject);
return; return;
} }
efree(callback_name); STR_RELEASE(callback_name);
} }
SEPARATE_ZVAL(regex); SEPARATE_ZVAL(regex);

View file

@ -475,8 +475,8 @@ PHP_FUNCTION(spl_autoload_call)
Register given function as __autoload() implementation */ Register given function as __autoload() implementation */
PHP_FUNCTION(spl_autoload_register) PHP_FUNCTION(spl_autoload_register)
{ {
char *func_name, *error = NULL; zend_string *func_name;
int func_name_len; char *error = NULL;
zend_string *lc_name; zend_string *lc_name;
zval *zcallable = NULL; zval *zcallable = NULL;
zend_bool do_throw = 1; zend_bool do_throw = 1;
@ -491,7 +491,7 @@ PHP_FUNCTION(spl_autoload_register)
} }
if (ZEND_NUM_ARGS()) { if (ZEND_NUM_ARGS()) {
if (!zend_is_callable_ex(zcallable, NULL, IS_CALLABLE_STRICT, &func_name, &func_name_len, &fcc, &error TSRMLS_CC)) { if (!zend_is_callable_ex(zcallable, NULL, IS_CALLABLE_STRICT, &func_name, &fcc, &error TSRMLS_CC)) {
alfi.ce = fcc.calling_scope; alfi.ce = fcc.calling_scope;
alfi.func_ptr = fcc.function_handler; alfi.func_ptr = fcc.function_handler;
obj_ptr = fcc.object_ptr; obj_ptr = fcc.object_ptr;
@ -503,7 +503,7 @@ PHP_FUNCTION(spl_autoload_register)
if (error) { if (error) {
efree(error); efree(error);
} }
efree(func_name); STR_RELEASE(func_name);
RETURN_FALSE; RETURN_FALSE;
} else if (do_throw) { } else if (do_throw) {
zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Passed array does not specify %s %smethod (%s)", alfi.func_ptr ? "a callable" : "an existing", !obj_ptr ? "static " : "", error); zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Passed array does not specify %s %smethod (%s)", alfi.func_ptr ? "a callable" : "an existing", !obj_ptr ? "static " : "", error);
@ -511,16 +511,16 @@ PHP_FUNCTION(spl_autoload_register)
if (error) { if (error) {
efree(error); efree(error);
} }
efree(func_name); STR_RELEASE(func_name);
RETURN_FALSE; RETURN_FALSE;
} else if (Z_TYPE_P(zcallable) == IS_STRING) { } else if (Z_TYPE_P(zcallable) == IS_STRING) {
if (do_throw) { if (do_throw) {
zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Function '%s' not %s (%s)", func_name, alfi.func_ptr ? "callable" : "found", error); zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Function '%s' not %s (%s)", func_name->val, alfi.func_ptr ? "callable" : "found", error);
} }
if (error) { if (error) {
efree(error); efree(error);
} }
efree(func_name); STR_RELEASE(func_name);
RETURN_FALSE; RETURN_FALSE;
} else { } else {
if (do_throw) { if (do_throw) {
@ -529,7 +529,7 @@ PHP_FUNCTION(spl_autoload_register)
if (error) { if (error) {
efree(error); efree(error);
} }
efree(func_name); STR_RELEASE(func_name);
RETURN_FALSE; RETURN_FALSE;
} }
} else if (fcc.function_handler->type == ZEND_INTERNAL_FUNCTION && } else if (fcc.function_handler->type == ZEND_INTERNAL_FUNCTION &&
@ -540,7 +540,7 @@ PHP_FUNCTION(spl_autoload_register)
if (error) { if (error) {
efree(error); efree(error);
} }
efree(func_name); STR_RELEASE(func_name);
RETURN_FALSE; RETURN_FALSE;
} }
alfi.closure = NULL; alfi.closure = NULL;
@ -555,15 +555,15 @@ PHP_FUNCTION(spl_autoload_register)
alfi.closure = zcallable; alfi.closure = zcallable;
Z_ADDREF_P(zcallable); Z_ADDREF_P(zcallable);
lc_name = STR_ALLOC(func_name_len + sizeof(zend_uint), 0); lc_name = STR_ALLOC(func_name->len + sizeof(zend_uint), 0);
zend_str_tolower_copy(lc_name->val, func_name, func_name_len); zend_str_tolower_copy(lc_name->val, func_name->val, func_name->len);
memcpy(lc_name->val + func_name_len, &Z_OBJ_HANDLE_P(zcallable), sizeof(zend_uint)); memcpy(lc_name->val + func_name->len, &Z_OBJ_HANDLE_P(zcallable), sizeof(zend_uint));
lc_name->val[lc_name->len] = '\0'; lc_name->val[lc_name->len] = '\0';
} else { } else {
lc_name = STR_ALLOC(func_name_len, 0); lc_name = STR_ALLOC(func_name->len, 0);
zend_str_tolower_copy(lc_name->val, func_name, func_name_len); zend_str_tolower_copy(lc_name->val, func_name->val, func_name->len);
} }
efree(func_name); STR_RELEASE(func_name);
if (SPL_G(autoload_functions) && zend_hash_exists(SPL_G(autoload_functions), lc_name)) { if (SPL_G(autoload_functions) && zend_hash_exists(SPL_G(autoload_functions), lc_name)) {
if (alfi.closure) { if (alfi.closure) {
@ -634,8 +634,8 @@ skip:
Unregister given function as __autoload() implementation */ Unregister given function as __autoload() implementation */
PHP_FUNCTION(spl_autoload_unregister) PHP_FUNCTION(spl_autoload_unregister)
{ {
char *func_name, *error = NULL; zend_string *func_name = NULL;
int func_name_len; char *error = NULL;
zend_string *lc_name; zend_string *lc_name;
zval *zcallable; zval *zcallable;
int success = FAILURE; int success = FAILURE;
@ -647,13 +647,13 @@ PHP_FUNCTION(spl_autoload_unregister)
return; return;
} }
if (!zend_is_callable_ex(zcallable, NULL, IS_CALLABLE_CHECK_SYNTAX_ONLY, &func_name, &func_name_len, &fcc, &error TSRMLS_CC)) { if (!zend_is_callable_ex(zcallable, NULL, IS_CALLABLE_CHECK_SYNTAX_ONLY, &func_name, &fcc, &error TSRMLS_CC)) {
zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Unable to unregister invalid function (%s)", error); zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Unable to unregister invalid function (%s)", error);
if (error) { if (error) {
efree(error); efree(error);
} }
if (func_name) { if (func_name) {
efree(func_name); STR_RELEASE(func_name);
} }
RETURN_FALSE; RETURN_FALSE;
} }
@ -663,19 +663,19 @@ PHP_FUNCTION(spl_autoload_unregister)
} }
if (Z_TYPE_P(zcallable) == IS_OBJECT) { if (Z_TYPE_P(zcallable) == IS_OBJECT) {
lc_name = STR_ALLOC(func_name_len + 2 + sizeof(zend_uint), 0); lc_name = STR_ALLOC(func_name->len + 2 + sizeof(zend_uint), 0);
zend_str_tolower_copy(lc_name->val, func_name, func_name_len); zend_str_tolower_copy(lc_name->val, func_name->val, func_name->len);
memcpy(lc_name->val + func_name_len, &Z_OBJ_HANDLE_P(zcallable), sizeof(zend_uint)); memcpy(lc_name->val + func_name->len, &Z_OBJ_HANDLE_P(zcallable), sizeof(zend_uint));
lc_name->len += sizeof(zend_uint); lc_name->len += sizeof(zend_uint);
lc_name->val[lc_name->len] = '\0'; lc_name->val[lc_name->len] = '\0';
} else { } else {
lc_name = STR_ALLOC(func_name_len, 0); lc_name = STR_ALLOC(func_name->len, 0);
zend_str_tolower_copy(lc_name->val, func_name, func_name_len); zend_str_tolower_copy(lc_name->val, func_name->val, func_name->len);
} }
efree(func_name); STR_RELEASE(func_name);
if (SPL_G(autoload_functions)) { if (SPL_G(autoload_functions)) {
if (func_name_len == sizeof("spl_autoload_call") - 1 && !strcmp(lc_name->val, "spl_autoload_call")) { if (lc_name->len == sizeof("spl_autoload_call") - 1 && !strcmp(lc_name->val, "spl_autoload_call")) {
/* remove all */ /* remove all */
zend_hash_destroy(SPL_G(autoload_functions)); zend_hash_destroy(SPL_G(autoload_functions));
FREE_HASHTABLE(SPL_G(autoload_functions)); FREE_HASHTABLE(SPL_G(autoload_functions));
@ -692,7 +692,7 @@ PHP_FUNCTION(spl_autoload_unregister)
success = zend_hash_del(SPL_G(autoload_functions), lc_name); success = zend_hash_del(SPL_G(autoload_functions), lc_name);
} }
} }
} else if (func_name_len == sizeof("spl_autoload")-1 && !strcmp(lc_name->val, "spl_autoload")) { } else if (lc_name->len == sizeof("spl_autoload")-1 && !strcmp(lc_name->val, "spl_autoload")) {
/* register single spl_autoload() */ /* register single spl_autoload() */
spl_func_ptr = zend_hash_str_find_ptr(EG(function_table), "spl_autoload", sizeof("spl_autoload")); spl_func_ptr = zend_hash_str_find_ptr(EG(function_table), "spl_autoload", sizeof("spl_autoload"));

View file

@ -4987,17 +4987,17 @@ static int user_shutdown_function_call(zval *zv TSRMLS_DC) /* {{{ */
{ {
php_shutdown_function_entry *shutdown_function_entry = Z_PTR_P(zv); php_shutdown_function_entry *shutdown_function_entry = Z_PTR_P(zv);
zval retval; zval retval;
char *function_name; zend_string *function_name;
if (!zend_is_callable(&shutdown_function_entry->arguments[0], 0, &function_name TSRMLS_CC)) { if (!zend_is_callable(&shutdown_function_entry->arguments[0], 0, &function_name TSRMLS_CC)) {
php_error(E_WARNING, "(Registered shutdown functions) Unable to call %s() - function does not exist", function_name); php_error(E_WARNING, "(Registered shutdown functions) Unable to call %s() - function does not exist", function_name->val);
if (function_name) { if (function_name) {
efree(function_name); STR_RELEASE(function_name);
} }
return 0; return 0;
} }
if (function_name) { if (function_name) {
efree(function_name); STR_RELEASE(function_name);
} }
if (call_user_function(EG(function_table), NULL, if (call_user_function(EG(function_table), NULL,
@ -5120,7 +5120,7 @@ void php_free_shutdown_functions(TSRMLS_D) /* {{{ */
PHP_FUNCTION(register_shutdown_function) PHP_FUNCTION(register_shutdown_function)
{ {
php_shutdown_function_entry shutdown_function_entry; php_shutdown_function_entry shutdown_function_entry;
char *callback_name = NULL; zend_string *callback_name = NULL;
int i; int i;
shutdown_function_entry.arg_count = ZEND_NUM_ARGS(); shutdown_function_entry.arg_count = ZEND_NUM_ARGS();
@ -5138,7 +5138,7 @@ PHP_FUNCTION(register_shutdown_function)
/* Prevent entering of anything but valid callback (syntax check only!) */ /* Prevent entering of anything but valid callback (syntax check only!) */
if (!zend_is_callable(&shutdown_function_entry.arguments[0], 0, &callback_name TSRMLS_CC)) { if (!zend_is_callable(&shutdown_function_entry.arguments[0], 0, &callback_name TSRMLS_CC)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid shutdown callback '%s' passed", callback_name); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid shutdown callback '%s' passed", callback_name->val);
efree(shutdown_function_entry.arguments); efree(shutdown_function_entry.arguments);
RETVAL_FALSE; RETVAL_FALSE;
} else { } else {
@ -5153,7 +5153,7 @@ PHP_FUNCTION(register_shutdown_function)
zend_hash_next_index_insert_mem(BG(user_shutdown_function_names), &shutdown_function_entry, sizeof(php_shutdown_function_entry)); zend_hash_next_index_insert_mem(BG(user_shutdown_function_names), &shutdown_function_entry, sizeof(php_shutdown_function_entry));
} }
if (callback_name) { if (callback_name) {
efree(callback_name); STR_RELEASE(callback_name);
} }
} }
/* }}} */ /* }}} */
@ -5730,7 +5730,7 @@ PHP_FUNCTION(register_tick_function)
{ {
user_tick_function_entry tick_fe; user_tick_function_entry tick_fe;
int i; int i;
char *function_name = NULL; zend_string *function_name = NULL;
tick_fe.calling = 0; tick_fe.calling = 0;
tick_fe.arg_count = ZEND_NUM_ARGS(); tick_fe.arg_count = ZEND_NUM_ARGS();
@ -5748,11 +5748,11 @@ PHP_FUNCTION(register_tick_function)
if (!zend_is_callable(&tick_fe.arguments[0], 0, &function_name TSRMLS_CC)) { if (!zend_is_callable(&tick_fe.arguments[0], 0, &function_name TSRMLS_CC)) {
efree(tick_fe.arguments); efree(tick_fe.arguments);
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid tick callback '%s' passed", function_name); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid tick callback '%s' passed", function_name->val);
efree(function_name); STR_RELEASE(function_name);
RETURN_FALSE; RETURN_FALSE;
} else if (function_name) { } else if (function_name) {
efree(function_name); STR_RELEASE(function_name);
} }
if (Z_TYPE(tick_fe.arguments[0]) != IS_ARRAY && Z_TYPE(tick_fe.arguments[0]) != IS_OBJECT) { if (Z_TYPE(tick_fe.arguments[0]) != IS_ARRAY && Z_TYPE(tick_fe.arguments[0]) != IS_OBJECT) {

View file

@ -374,7 +374,7 @@ PHP_FUNCTION(is_scalar)
PHP_FUNCTION(is_callable) PHP_FUNCTION(is_callable)
{ {
zval *var, *callable_name = NULL; zval *var, *callable_name = NULL;
char *name; zend_string *name;
char *error; char *error;
zend_bool retval; zend_bool retval;
zend_bool syntax_only = 0; zend_bool syntax_only = 0;
@ -389,12 +389,14 @@ PHP_FUNCTION(is_callable)
check_flags |= IS_CALLABLE_CHECK_SYNTAX_ONLY; check_flags |= IS_CALLABLE_CHECK_SYNTAX_ONLY;
} }
if (ZEND_NUM_ARGS() > 2) { if (ZEND_NUM_ARGS() > 2) {
retval = zend_is_callable_ex(var, NULL, check_flags, &name, NULL, NULL, &error TSRMLS_CC); if (callable_name && Z_ISREF_P(callable_name)) {
callable_name = Z_REFVAL_P(callable_name);
}
retval = zend_is_callable_ex(var, NULL, check_flags, &name, NULL, &error TSRMLS_CC);
zval_dtor(callable_name); zval_dtor(callable_name);
//??? ZVAL_STRING(callable_name, name, 0); ZVAL_STR(callable_name, name);
ZVAL_STRING(callable_name, name);
} else { } else {
retval = zend_is_callable_ex(var, NULL, check_flags, NULL, NULL, NULL, &error TSRMLS_CC); retval = zend_is_callable_ex(var, NULL, check_flags, NULL, NULL, &error TSRMLS_CC);
} }
if (error) { if (error) {
/* ignore errors */ /* ignore errors */

View file

@ -129,18 +129,15 @@ SAPI_API void sapi_free_header(sapi_header_struct *sapi_header)
PHP_FUNCTION(header_register_callback) PHP_FUNCTION(header_register_callback)
{ {
zval *callback_func; zval *callback_func;
char *callback_name;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &callback_func) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &callback_func) == FAILURE) {
return; return;
} }
if (!zend_is_callable(callback_func, 0, &callback_name TSRMLS_CC)) { if (!zend_is_callable(callback_func, 0, NULL TSRMLS_CC)) {
efree(callback_name);
RETURN_FALSE; RETURN_FALSE;
} }
efree(callback_name);
if (Z_TYPE(SG(callback_func)) != IS_UNDEF) { if (Z_TYPE(SG(callback_func)) != IS_UNDEF) {
zval_ptr_dtor(&SG(callback_func)); zval_ptr_dtor(&SG(callback_func));
SG(fci_cache) = empty_fcall_info_cache; SG(fci_cache) = empty_fcall_info_cache;
@ -156,11 +153,10 @@ static void sapi_run_header_callback(TSRMLS_D)
{ {
int error; int error;
zend_fcall_info fci; zend_fcall_info fci;
char *callback_name = NULL;
char *callback_error = NULL; char *callback_error = NULL;
zval retval; zval retval;
if (zend_fcall_info_init(&SG(callback_func), 0, &fci, &SG(fci_cache), &callback_name, &callback_error TSRMLS_CC) == SUCCESS) { if (zend_fcall_info_init(&SG(callback_func), 0, &fci, &SG(fci_cache), NULL, &callback_error TSRMLS_CC) == SUCCESS) {
fci.retval = &retval; fci.retval = &retval;
error = zend_call_function(&fci, &SG(fci_cache) TSRMLS_CC); error = zend_call_function(&fci, &SG(fci_cache) TSRMLS_CC);
@ -174,9 +170,6 @@ callback_failed:
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not call the sapi_header_callback"); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not call the sapi_header_callback");
} }
if (callback_name) {
efree(callback_name);
}
if (callback_error) { if (callback_error) {
efree(callback_error); efree(callback_error);
} }

View file

@ -476,7 +476,8 @@ PHPAPI int php_output_start_internal(const char *name, size_t name_len, php_outp
* Create a user level output handler */ * Create a user level output handler */
PHPAPI php_output_handler *php_output_handler_create_user(zval *output_handler, size_t chunk_size, int flags TSRMLS_DC) PHPAPI php_output_handler *php_output_handler_create_user(zval *output_handler, size_t chunk_size, int flags TSRMLS_DC)
{ {
char *handler_name = NULL, *error = NULL; zend_string *handler_name = NULL;
char *error = NULL;
php_output_handler *handler = NULL; php_output_handler *handler = NULL;
php_output_handler_alias_ctor_t alias = NULL; php_output_handler_alias_ctor_t alias = NULL;
php_output_handler_user_func_t *user = NULL; php_output_handler_user_func_t *user = NULL;
@ -493,7 +494,7 @@ PHPAPI php_output_handler *php_output_handler_create_user(zval *output_handler,
default: default:
user = ecalloc(1, sizeof(php_output_handler_user_func_t)); user = ecalloc(1, sizeof(php_output_handler_user_func_t));
if (SUCCESS == zend_fcall_info_init(output_handler, 0, &user->fci, &user->fcc, &handler_name, &error TSRMLS_CC)) { if (SUCCESS == zend_fcall_info_init(output_handler, 0, &user->fci, &user->fcc, &handler_name, &error TSRMLS_CC)) {
handler = php_output_handler_init(handler_name, strlen(handler_name), chunk_size, (flags & ~0xf) | PHP_OUTPUT_HANDLER_USER TSRMLS_CC); handler = php_output_handler_init(handler_name->val, handler_name->len, chunk_size, (flags & ~0xf) | PHP_OUTPUT_HANDLER_USER TSRMLS_CC);
Z_ADDREF_P(output_handler); Z_ADDREF_P(output_handler);
user->zoh = output_handler; user->zoh = output_handler;
handler->func.user = user; handler->func.user = user;
@ -505,7 +506,7 @@ PHPAPI php_output_handler *php_output_handler_create_user(zval *output_handler,
efree(error); efree(error);
} }
if (handler_name) { if (handler_name) {
efree(handler_name); STR_RELEASE(handler_name);
} }
} }

View file

@ -977,7 +977,7 @@ static int php_userstreamop_set_option(php_stream *stream, int option, int value
switch (value) { switch (value) {
case PHP_STREAM_TRUNCATE_SUPPORTED: case PHP_STREAM_TRUNCATE_SUPPORTED:
if (zend_is_callable_ex(&func_name, us->object, IS_CALLABLE_CHECK_SILENT, if (zend_is_callable_ex(&func_name, us->object, IS_CALLABLE_CHECK_SILENT,
NULL, NULL, NULL, NULL TSRMLS_CC)) NULL, NULL, NULL TSRMLS_CC))
ret = PHP_STREAM_OPTION_RETURN_OK; ret = PHP_STREAM_OPTION_RETURN_OK;
else else
ret = PHP_STREAM_OPTION_RETURN_ERR; ret = PHP_STREAM_OPTION_RETURN_ERR;