mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Fixed is_callable/call_user_func mess that had done different things for very similar arguments e.g. array("A","B") and "A::B"
This commit is contained in:
parent
77baec3f6d
commit
af05ce0af6
17 changed files with 223 additions and 417 deletions
|
@ -99,8 +99,6 @@ var_dump($x->doSomethingStatic(1));
|
||||||
--EXPECTF--
|
--EXPECTF--
|
||||||
===A===
|
===A===
|
||||||
TestB::doSomething(1)
|
TestB::doSomething(1)
|
||||||
|
|
||||||
Strict Standards: call_user_func_array() expects parameter 1 to be a valid callback, non-static method TestA::doSomething() should not be called statically, assuming $this from compatible context TestB in %s on line %d
|
|
||||||
TestA::doSomething(2)
|
TestA::doSomething(2)
|
||||||
int(1)
|
int(1)
|
||||||
|
|
||||||
|
@ -111,8 +109,6 @@ int(1)
|
||||||
|
|
||||||
===C===
|
===C===
|
||||||
TestB::doSomethingParent(1)
|
TestB::doSomethingParent(1)
|
||||||
|
|
||||||
Strict Standards: call_user_func_array() expects parameter 1 to be a valid callback, non-static method TestA::doSomethingParent() should not be called statically, assuming $this from compatible context TestB in %s on line %d
|
|
||||||
TestA::doSomethingParent(2)
|
TestA::doSomethingParent(2)
|
||||||
int(1)
|
int(1)
|
||||||
|
|
||||||
|
|
|
@ -37,8 +37,6 @@ object(foo)#%d (0) {
|
||||||
|
|
||||||
Strict Standards: call_user_func() expects parameter 1 to be a valid callback, non-static method foo::test() should not be called statically in %s on line %d
|
Strict Standards: call_user_func() expects parameter 1 to be a valid callback, non-static method foo::test() should not be called statically in %s on line %d
|
||||||
|
|
||||||
Strict Standards: Non-static method foo::test() should not be called statically in %s on line %d
|
|
||||||
|
|
||||||
Strict Standards: Non-static method bar::show() should not be called statically in %s on line %d
|
Strict Standards: Non-static method bar::show() should not be called statically in %s on line %d
|
||||||
object(foo)#%d (0) {
|
object(foo)#%d (0) {
|
||||||
}
|
}
|
||||||
|
|
162
Zend/zend_API.c
162
Zend/zend_API.c
|
@ -2318,6 +2318,9 @@ static int zend_is_callable_check_class(char *name, int name_len, zend_fcall_inf
|
||||||
} else {
|
} else {
|
||||||
fcc->called_scope = EG(called_scope);
|
fcc->called_scope = EG(called_scope);
|
||||||
fcc->calling_scope = EG(scope);
|
fcc->calling_scope = EG(scope);
|
||||||
|
if (!fcc->object_pp) {
|
||||||
|
fcc->object_pp = EG(This) ? &EG(This) : NULL;
|
||||||
|
}
|
||||||
ret = 1;
|
ret = 1;
|
||||||
}
|
}
|
||||||
} else if (name_len == sizeof("parent") - 1 &&
|
} else if (name_len == sizeof("parent") - 1 &&
|
||||||
|
@ -2329,6 +2332,9 @@ static int zend_is_callable_check_class(char *name, int name_len, zend_fcall_inf
|
||||||
} else {
|
} else {
|
||||||
fcc->called_scope = EG(called_scope);
|
fcc->called_scope = EG(called_scope);
|
||||||
fcc->calling_scope = EG(scope)->parent;
|
fcc->calling_scope = EG(scope)->parent;
|
||||||
|
if (!fcc->object_pp) {
|
||||||
|
fcc->object_pp = EG(This) ? &EG(This) : NULL;
|
||||||
|
}
|
||||||
ret = 1;
|
ret = 1;
|
||||||
}
|
}
|
||||||
} else if (name_len == sizeof("static") - 1 &&
|
} else if (name_len == sizeof("static") - 1 &&
|
||||||
|
@ -2338,10 +2344,23 @@ static int zend_is_callable_check_class(char *name, int name_len, zend_fcall_inf
|
||||||
} else {
|
} else {
|
||||||
fcc->called_scope = EG(called_scope);
|
fcc->called_scope = EG(called_scope);
|
||||||
fcc->calling_scope = EG(called_scope);
|
fcc->calling_scope = EG(called_scope);
|
||||||
|
if (!fcc->object_pp) {
|
||||||
|
fcc->object_pp = EG(This) ? &EG(This) : NULL;
|
||||||
|
}
|
||||||
ret = 1;
|
ret = 1;
|
||||||
}
|
}
|
||||||
} else if (zend_lookup_class_ex(name, name_len, 1, &pce TSRMLS_CC) == SUCCESS) {
|
} else if (zend_lookup_class_ex(name, name_len, 1, &pce TSRMLS_CC) == SUCCESS) {
|
||||||
fcc->called_scope = fcc->calling_scope = *pce;
|
zend_class_entry *scope = EG(active_op_array) ? EG(active_op_array)->scope : NULL;
|
||||||
|
|
||||||
|
fcc->calling_scope = *pce;
|
||||||
|
if (scope && !fcc->object_pp && EG(This) &&
|
||||||
|
instanceof_function(Z_OBJCE_P(EG(This)), scope TSRMLS_CC) &&
|
||||||
|
instanceof_function(scope, fcc->calling_scope TSRMLS_CC)) {
|
||||||
|
fcc->object_pp = &EG(This);
|
||||||
|
fcc->called_scope = Z_OBJCE_PP(fcc->object_pp);
|
||||||
|
} else {
|
||||||
|
fcc->called_scope = fcc->object_pp ? Z_OBJCE_PP(fcc->object_pp) : fcc->calling_scope;
|
||||||
|
}
|
||||||
ret = 1;
|
ret = 1;
|
||||||
} else {
|
} else {
|
||||||
if (error) zend_spprintf(error, 0, "class '%.*s' not found", name_len, name);
|
if (error) zend_spprintf(error, 0, "class '%.*s' not found", name_len, name);
|
||||||
|
@ -2355,8 +2374,8 @@ static int zend_is_callable_check_class(char *name, int name_len, zend_fcall_inf
|
||||||
static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fcall_info_cache *fcc, char **error TSRMLS_DC) /* {{{ */
|
static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fcall_info_cache *fcc, char **error TSRMLS_DC) /* {{{ */
|
||||||
{
|
{
|
||||||
zend_class_entry *ce_org = fcc->calling_scope;
|
zend_class_entry *ce_org = fcc->calling_scope;
|
||||||
int retval;
|
int retval = 0;
|
||||||
char *lmname, *colon;
|
char *mname, *lmname, *colon;
|
||||||
int clen, mlen;
|
int clen, mlen;
|
||||||
zend_class_entry *last_scope;
|
zend_class_entry *last_scope;
|
||||||
HashTable *ftable;
|
HashTable *ftable;
|
||||||
|
@ -2375,9 +2394,11 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca
|
||||||
Z_STRVAL_P(callable)[1] == ':'
|
Z_STRVAL_P(callable)[1] == ':'
|
||||||
) {
|
) {
|
||||||
mlen = Z_STRLEN_P(callable) - 2;
|
mlen = Z_STRLEN_P(callable) - 2;
|
||||||
|
mname = Z_STRVAL_P(callable) + 2;
|
||||||
lmname = zend_str_tolower_dup(Z_STRVAL_P(callable) + 2, mlen);
|
lmname = zend_str_tolower_dup(Z_STRVAL_P(callable) + 2, mlen);
|
||||||
} else {
|
} else {
|
||||||
mlen = Z_STRLEN_P(callable);
|
mlen = Z_STRLEN_P(callable);
|
||||||
|
mname = Z_STRVAL_P(callable);
|
||||||
lmname = zend_str_tolower_dup(Z_STRVAL_P(callable), mlen);
|
lmname = zend_str_tolower_dup(Z_STRVAL_P(callable), mlen);
|
||||||
}
|
}
|
||||||
/* Check if function with given name exists.
|
/* Check if function with given name exists.
|
||||||
|
@ -2397,7 +2418,6 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca
|
||||||
colon--;
|
colon--;
|
||||||
clen = colon - Z_STRVAL_P(callable);
|
clen = colon - Z_STRVAL_P(callable);
|
||||||
mlen = Z_STRLEN_P(callable) - clen - 2;
|
mlen = Z_STRLEN_P(callable) - clen - 2;
|
||||||
lmname = colon + 2;
|
|
||||||
|
|
||||||
if (colon == Z_STRVAL_P(callable)) {
|
if (colon == Z_STRVAL_P(callable)) {
|
||||||
if (error) zend_spprintf(error, 0, "invalid function name");
|
if (error) zend_spprintf(error, 0, "invalid function name");
|
||||||
|
@ -2422,53 +2442,41 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca
|
||||||
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, fcc->calling_scope->name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
lmname = zend_str_tolower_dup(Z_STRVAL_P(callable) + clen + 2, mlen);
|
mname = Z_STRVAL_P(callable) + clen + 2;
|
||||||
} else if (ce_org) {
|
} else if (ce_org) {
|
||||||
/* Try to fetch find static method of given class. */
|
/* Try to fetch find static method of given class. */
|
||||||
mlen = Z_STRLEN_P(callable);
|
mlen = Z_STRLEN_P(callable);
|
||||||
lmname = zend_str_tolower_dup(Z_STRVAL_P(callable), Z_STRLEN_P(callable));
|
mname = Z_STRVAL_P(callable);
|
||||||
ftable = &ce_org->function_table;
|
ftable = &ce_org->function_table;
|
||||||
fcc->calling_scope = ce_org;
|
fcc->calling_scope = ce_org;
|
||||||
} else {
|
} else {
|
||||||
/* We already checked for plain function before. */
|
/* We already checked for plain function before. */
|
||||||
if (error) zend_spprintf(error, 0, "function '%s' not found or invalid function name", Z_STRVAL_P(callable));
|
if (error && !(check_flags & IS_CALLABLE_CHECK_SILENT)) {
|
||||||
|
zend_spprintf(error, 0, "function '%s' not found or invalid function name", Z_STRVAL_P(callable));
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = zend_hash_find(ftable, lmname, mlen+1, (void**)&fcc->function_handler) == SUCCESS ? 1 : 0;
|
lmname = zend_str_tolower_dup(mname, mlen);
|
||||||
|
if (zend_hash_find(ftable, lmname, mlen+1, (void**)&fcc->function_handler) == SUCCESS) {
|
||||||
if (!retval) {
|
retval = 1;
|
||||||
if (fcc->object_pp && fcc->calling_scope && fcc->calling_scope->__call != 0) {
|
} else if (fcc->object_pp && Z_OBJ_HT_PP(fcc->object_pp)->get_method) {
|
||||||
retval = 1;
|
fcc->function_handler = Z_OBJ_HT_PP(fcc->object_pp)->get_method(fcc->object_pp, mname, mlen TSRMLS_CC);
|
||||||
call_via_handler = 1;
|
retval = fcc->function_handler ? 1 : 0;
|
||||||
fcc->function_handler = fcc->calling_scope->__call;
|
call_via_handler = 1;
|
||||||
|
} else if (fcc->calling_scope) {
|
||||||
|
if (fcc->calling_scope->get_static_method) {
|
||||||
|
fcc->function_handler = fcc->calling_scope->get_static_method(fcc->calling_scope, mname, mlen TSRMLS_CC);
|
||||||
} else {
|
} else {
|
||||||
if (!fcc->object_pp && fcc->calling_scope && (fcc->calling_scope->__callstatic || fcc->calling_scope->__call)) {
|
fcc->function_handler = zend_std_get_static_method(fcc->calling_scope, mname, mlen TSRMLS_CC);
|
||||||
if (fcc->calling_scope->__call &&
|
|
||||||
EG(This) &&
|
|
||||||
Z_OBJ_HT_P(EG(This))->get_class_entry &&
|
|
||||||
instanceof_function(Z_OBJCE_P(EG(This)), fcc->calling_scope TSRMLS_CC)) {
|
|
||||||
retval = 1;
|
|
||||||
call_via_handler = 1;
|
|
||||||
fcc->function_handler = fcc->calling_scope->__call;
|
|
||||||
fcc->object_pp = &EG(This);
|
|
||||||
} else if (fcc->calling_scope->__callstatic) {
|
|
||||||
retval = 1;
|
|
||||||
call_via_handler = 1;
|
|
||||||
fcc->function_handler = fcc->calling_scope->__callstatic;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (retval == 0) {
|
|
||||||
if (fcc->calling_scope) {
|
|
||||||
if (error) zend_spprintf(error, 0, "class '%s' does not have a method '%s'", fcc->calling_scope->name, lmname);
|
|
||||||
} else {
|
|
||||||
if (error) zend_spprintf(error, 0, "function '%s' does not exist", lmname);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
retval = fcc->function_handler ? 1 : 0;
|
||||||
if (fcc->calling_scope) {
|
call_via_handler = 1;
|
||||||
|
}
|
||||||
|
efree(lmname);
|
||||||
|
|
||||||
|
if (retval) {
|
||||||
|
if (fcc->calling_scope && !call_via_handler) {
|
||||||
if (!fcc->object_pp && !(fcc->function_handler->common.fn_flags & ZEND_ACC_STATIC)) {
|
if (!fcc->object_pp && !(fcc->function_handler->common.fn_flags & ZEND_ACC_STATIC)) {
|
||||||
int severity;
|
int severity;
|
||||||
char *verb;
|
char *verb;
|
||||||
|
@ -2500,7 +2508,7 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca
|
||||||
}
|
}
|
||||||
if (retval && (check_flags & IS_CALLABLE_CHECK_NO_ACCESS) == 0) {
|
if (retval && (check_flags & IS_CALLABLE_CHECK_NO_ACCESS) == 0) {
|
||||||
if (fcc->function_handler->op_array.fn_flags & ZEND_ACC_PRIVATE) {
|
if (fcc->function_handler->op_array.fn_flags & ZEND_ACC_PRIVATE) {
|
||||||
if (!zend_check_private(fcc->function_handler, fcc->object_pp ? Z_OBJCE_PP(fcc->object_pp) : EG(scope), lmname, mlen TSRMLS_CC)) {
|
if (!zend_check_private(fcc->function_handler, fcc->object_pp ? Z_OBJCE_PP(fcc->object_pp) : EG(scope), mname, mlen TSRMLS_CC)) {
|
||||||
if (error) {
|
if (error) {
|
||||||
if (*error) {
|
if (*error) {
|
||||||
efree(*error);
|
efree(*error);
|
||||||
|
@ -2522,20 +2530,26 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (error && !(check_flags & IS_CALLABLE_CHECK_SILENT)) {
|
||||||
|
if (fcc->calling_scope) {
|
||||||
|
if (error) zend_spprintf(error, 0, "class '%s' does not have a method '%s'", fcc->calling_scope->name, mname);
|
||||||
|
} else {
|
||||||
|
if (error) zend_spprintf(error, 0, "function '%s' does not exist", mname);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (fcc->object_pp) {
|
if (fcc->object_pp) {
|
||||||
fcc->called_scope = Z_OBJCE_PP(fcc->object_pp);
|
fcc->called_scope = Z_OBJCE_PP(fcc->object_pp);
|
||||||
}
|
}
|
||||||
efree(lmname);
|
if (retval) {
|
||||||
if (retval && !call_via_handler) {
|
|
||||||
fcc->initialized = 1;
|
fcc->initialized = 1;
|
||||||
}
|
}
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
ZEND_API zend_bool zend_is_callable_ex(zval *callable, 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_pp, uint check_flags, char **callable_name, int *callable_name_len, zend_fcall_info_cache *fcc, char **error TSRMLS_DC) /* {{{ */
|
||||||
{
|
{
|
||||||
|
zend_bool ret;
|
||||||
int callable_name_len_local;
|
int callable_name_len_local;
|
||||||
zend_fcall_info_cache fcc_local;
|
zend_fcall_info_cache fcc_local;
|
||||||
|
|
||||||
|
@ -2561,15 +2575,42 @@ ZEND_API zend_bool zend_is_callable_ex(zval *callable, uint check_flags, char **
|
||||||
|
|
||||||
switch (Z_TYPE_P(callable)) {
|
switch (Z_TYPE_P(callable)) {
|
||||||
case IS_STRING:
|
case IS_STRING:
|
||||||
if (callable_name) {
|
if (object_pp && *object_pp) {
|
||||||
|
fcc->object_pp = object_pp;
|
||||||
|
fcc->calling_scope = Z_OBJCE_PP(object_pp);
|
||||||
|
if (callable_name) {
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
|
*callable_name_len = fcc->calling_scope->name_length + Z_STRLEN_P(callable) + sizeof("::") - 1;
|
||||||
|
ptr = *callable_name = emalloc(*callable_name_len + 1);
|
||||||
|
memcpy(ptr, fcc->calling_scope->name, fcc->calling_scope->name_length);
|
||||||
|
ptr += fcc->calling_scope->name_length;
|
||||||
|
memcpy(ptr, "::", sizeof("::") - 1);
|
||||||
|
ptr += sizeof("::") - 1;
|
||||||
|
memcpy(ptr, Z_STRVAL_P(callable), Z_STRLEN_P(callable) + 1);
|
||||||
|
}
|
||||||
|
} else if (callable_name) {
|
||||||
*callable_name = estrndup(Z_STRVAL_P(callable), Z_STRLEN_P(callable));
|
*callable_name = estrndup(Z_STRVAL_P(callable), Z_STRLEN_P(callable));
|
||||||
*callable_name_len = Z_STRLEN_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;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return zend_is_callable_check_func(check_flags, callable, fcc, error TSRMLS_CC);
|
ret = zend_is_callable_check_func(check_flags, callable, fcc, error TSRMLS_CC);
|
||||||
|
if (fcc == &fcc_local &&
|
||||||
|
fcc->function_handler &&
|
||||||
|
((fcc->function_handler->type == ZEND_INTERNAL_FUNCTION &&
|
||||||
|
(fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER)) ||
|
||||||
|
fcc->function_handler->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY ||
|
||||||
|
fcc->function_handler->type == ZEND_OVERLOADED_FUNCTION)) {
|
||||||
|
if (fcc->function_handler->type != ZEND_OVERLOADED_FUNCTION) {
|
||||||
|
efree(fcc->function_handler->common.function_name);
|
||||||
|
}
|
||||||
|
efree(fcc->function_handler);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
|
||||||
case IS_ARRAY:
|
case IS_ARRAY:
|
||||||
{
|
{
|
||||||
|
@ -2629,7 +2670,20 @@ ZEND_API zend_bool zend_is_callable_ex(zval *callable, uint check_flags, char **
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return zend_is_callable_check_func(check_flags, *method, fcc, error TSRMLS_CC);
|
ret = zend_is_callable_check_func(check_flags, *method, fcc, error TSRMLS_CC);
|
||||||
|
if (fcc == &fcc_local &&
|
||||||
|
fcc->function_handler &&
|
||||||
|
((fcc->function_handler->type == ZEND_INTERNAL_FUNCTION &&
|
||||||
|
(fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER)) ||
|
||||||
|
fcc->function_handler->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY ||
|
||||||
|
fcc->function_handler->type == ZEND_OVERLOADED_FUNCTION)) {
|
||||||
|
if (fcc->function_handler->type != ZEND_OVERLOADED_FUNCTION) {
|
||||||
|
efree(fcc->function_handler->common.function_name);
|
||||||
|
}
|
||||||
|
efree(fcc->function_handler);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (zend_hash_num_elements(Z_ARRVAL_P(callable)) == 2) {
|
if (zend_hash_num_elements(Z_ARRVAL_P(callable)) == 2) {
|
||||||
if (!obj || (Z_TYPE_PP(obj) != IS_STRING && Z_TYPE_PP(obj) != IS_OBJECT)) {
|
if (!obj || (Z_TYPE_PP(obj) != IS_STRING && Z_TYPE_PP(obj) != IS_OBJECT)) {
|
||||||
|
@ -2683,7 +2737,7 @@ ZEND_API zend_bool zend_is_callable(zval *callable, uint check_flags, char **cal
|
||||||
{
|
{
|
||||||
TSRMLS_FETCH();
|
TSRMLS_FETCH();
|
||||||
|
|
||||||
return zend_is_callable_ex(callable, check_flags, callable_name, NULL, NULL, NULL TSRMLS_CC);
|
return zend_is_callable_ex(callable, NULL, check_flags, callable_name, NULL, NULL, NULL TSRMLS_CC);
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
@ -2691,13 +2745,23 @@ ZEND_API zend_bool zend_make_callable(zval *callable, char **callable_name TSRML
|
||||||
{
|
{
|
||||||
zend_fcall_info_cache fcc;
|
zend_fcall_info_cache fcc;
|
||||||
|
|
||||||
if (zend_is_callable_ex(callable, IS_CALLABLE_STRICT, callable_name, NULL, &fcc, NULL TSRMLS_CC)) {
|
if (zend_is_callable_ex(callable, NULL, IS_CALLABLE_STRICT, callable_name, NULL, &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);
|
||||||
add_next_index_string(callable, fcc.calling_scope->name, 1);
|
add_next_index_string(callable, fcc.calling_scope->name, 1);
|
||||||
add_next_index_string(callable, fcc.function_handler->common.function_name, 1);
|
add_next_index_string(callable, fcc.function_handler->common.function_name, 1);
|
||||||
}
|
}
|
||||||
|
if (fcc.function_handler &&
|
||||||
|
((fcc.function_handler->type == ZEND_INTERNAL_FUNCTION &&
|
||||||
|
(fcc.function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER)) ||
|
||||||
|
fcc.function_handler->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY ||
|
||||||
|
fcc.function_handler->type == ZEND_OVERLOADED_FUNCTION)) {
|
||||||
|
if (fcc.function_handler->type != ZEND_OVERLOADED_FUNCTION) {
|
||||||
|
efree(fcc.function_handler->common.function_name);
|
||||||
|
}
|
||||||
|
efree(fcc.function_handler);
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2706,7 +2770,7 @@ 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, char **callable_name, char **error TSRMLS_DC) /* {{{ */
|
||||||
{
|
{
|
||||||
if (!zend_is_callable_ex(callable, check_flags, callable_name, NULL, fcc, error TSRMLS_CC)) {
|
if (!zend_is_callable_ex(callable, NULL, check_flags, callable_name, NULL, fcc, error TSRMLS_CC)) {
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -273,10 +273,11 @@ ZEND_API void zend_wrong_param_count(TSRMLS_D);
|
||||||
#define IS_CALLABLE_CHECK_SYNTAX_ONLY (1<<0)
|
#define IS_CALLABLE_CHECK_SYNTAX_ONLY (1<<0)
|
||||||
#define IS_CALLABLE_CHECK_NO_ACCESS (1<<1)
|
#define IS_CALLABLE_CHECK_NO_ACCESS (1<<1)
|
||||||
#define IS_CALLABLE_CHECK_IS_STATIC (1<<2)
|
#define IS_CALLABLE_CHECK_IS_STATIC (1<<2)
|
||||||
|
#define IS_CALLABLE_CHECK_SILENT (1<<3)
|
||||||
|
|
||||||
#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, 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_pp, 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(zval *callable, uint check_flags, char **callable_name);
|
ZEND_API zend_bool zend_is_callable(zval *callable, uint check_flags, char **callable_name);
|
||||||
ZEND_API zend_bool zend_make_callable(zval *callable, char **callable_name TSRMLS_DC);
|
ZEND_API zend_bool zend_make_callable(zval *callable, char **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);
|
||||||
|
|
|
@ -36,7 +36,6 @@ typedef struct _zend_closure {
|
||||||
zend_object std;
|
zend_object std;
|
||||||
zend_function func;
|
zend_function func;
|
||||||
zval *this_ptr;
|
zval *this_ptr;
|
||||||
zend_function *invoke;
|
|
||||||
} zend_closure;
|
} zend_closure;
|
||||||
|
|
||||||
static zend_class_entry *zend_ce_closure;
|
static zend_class_entry *zend_ce_closure;
|
||||||
|
@ -44,6 +43,7 @@ static zend_object_handlers closure_handlers;
|
||||||
|
|
||||||
ZEND_METHOD(Closure, __invoke) /* {{{ */
|
ZEND_METHOD(Closure, __invoke) /* {{{ */
|
||||||
{
|
{
|
||||||
|
zend_function *func = EG(current_execute_data)->function_state.function;
|
||||||
zval ***arguments;
|
zval ***arguments;
|
||||||
zval *closure_result_ptr = NULL;
|
zval *closure_result_ptr = NULL;
|
||||||
|
|
||||||
|
@ -51,16 +51,10 @@ ZEND_METHOD(Closure, __invoke) /* {{{ */
|
||||||
if (zend_get_parameters_array_ex(ZEND_NUM_ARGS(), arguments) == FAILURE) {
|
if (zend_get_parameters_array_ex(ZEND_NUM_ARGS(), arguments) == FAILURE) {
|
||||||
efree(arguments);
|
efree(arguments);
|
||||||
zend_error(E_ERROR, "Cannot get arguments for calling closure");
|
zend_error(E_ERROR, "Cannot get arguments for calling closure");
|
||||||
RETURN_FALSE;
|
RETVAL_FALSE;
|
||||||
}
|
} else if (call_user_function_ex(CG(function_table), NULL, this_ptr, &closure_result_ptr, ZEND_NUM_ARGS(), arguments, 1, NULL TSRMLS_CC) == FAILURE) {
|
||||||
|
RETVAL_FALSE;
|
||||||
if (call_user_function_ex(CG(function_table), NULL, this_ptr, &closure_result_ptr, ZEND_NUM_ARGS(), arguments, 1, NULL TSRMLS_CC) == FAILURE) {
|
} else if (closure_result_ptr) {
|
||||||
efree(arguments);
|
|
||||||
RETURN_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
efree(arguments);
|
|
||||||
if (closure_result_ptr) {
|
|
||||||
if (Z_ISREF_P(closure_result_ptr) && return_value_ptr) {
|
if (Z_ISREF_P(closure_result_ptr) && return_value_ptr) {
|
||||||
if (return_value) {
|
if (return_value) {
|
||||||
zval_ptr_dtor(&return_value);
|
zval_ptr_dtor(&return_value);
|
||||||
|
@ -70,13 +64,12 @@ ZEND_METHOD(Closure, __invoke) /* {{{ */
|
||||||
RETVAL_ZVAL(closure_result_ptr, 1, 1);
|
RETVAL_ZVAL(closure_result_ptr, 1, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
efree(arguments);
|
||||||
/* }}} */
|
|
||||||
|
|
||||||
const static zend_function_entry closure_functions[] = { /* {{{ */
|
/* destruct the function also, then - we have allocated it in get_method */
|
||||||
ZEND_ME(Closure, __invoke, NULL, 0)
|
efree(func->internal_function.function_name);
|
||||||
{NULL, NULL, NULL}
|
efree(func);
|
||||||
};
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
static zend_function *zend_closure_get_constructor(zval *object TSRMLS_DC) /* {{{ */
|
static zend_function *zend_closure_get_constructor(zval *object TSRMLS_DC) /* {{{ */
|
||||||
|
@ -123,18 +116,17 @@ static zend_function *zend_closure_get_method(zval **object_ptr, char *method_na
|
||||||
memcmp(lc_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
|
memcmp(lc_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
|
||||||
) {
|
) {
|
||||||
zend_closure *closure = (zend_closure *)zend_object_store_get_object(*object_ptr TSRMLS_CC);
|
zend_closure *closure = (zend_closure *)zend_object_store_get_object(*object_ptr TSRMLS_CC);
|
||||||
|
zend_function *invoke = (zend_function*)emalloc(sizeof(zend_function));
|
||||||
|
|
||||||
if (!closure->invoke) {
|
invoke->common = closure->func.common;
|
||||||
closure->invoke = (zend_function*)emalloc(sizeof(zend_function));
|
invoke->type = ZEND_INTERNAL_FUNCTION;
|
||||||
closure->invoke->common = closure->func.common;
|
invoke->internal_function.fn_flags = ZEND_ACC_CALL_VIA_HANDLER;
|
||||||
closure->invoke->type = ZEND_INTERNAL_FUNCTION;
|
invoke->internal_function.handler = ZEND_MN(Closure___invoke);
|
||||||
closure->invoke->internal_function.handler = ZEND_MN(Closure___invoke);
|
invoke->internal_function.module = 0;
|
||||||
closure->invoke->internal_function.module = 0;
|
invoke->internal_function.scope = zend_ce_closure;
|
||||||
closure->invoke->internal_function.scope = zend_ce_closure;
|
invoke->internal_function.function_name = estrndup(ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1);
|
||||||
closure->invoke->internal_function.function_name = ZEND_INVOKE_FUNC_NAME;
|
|
||||||
}
|
|
||||||
free_alloca(lc_name, use_heap);
|
free_alloca(lc_name, use_heap);
|
||||||
return (zend_function *)closure->invoke;
|
return invoke;
|
||||||
}
|
}
|
||||||
free_alloca(lc_name, use_heap);
|
free_alloca(lc_name, use_heap);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -195,10 +187,6 @@ static void zend_closure_free_storage(void *object TSRMLS_DC) /* {{{ */
|
||||||
zval_ptr_dtor(&closure->this_ptr);
|
zval_ptr_dtor(&closure->this_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (closure->invoke) {
|
|
||||||
efree(closure->invoke);
|
|
||||||
}
|
|
||||||
|
|
||||||
efree(closure);
|
efree(closure);
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
@ -224,7 +212,7 @@ void zend_register_closure_ce(TSRMLS_D) /* {{{ */
|
||||||
{
|
{
|
||||||
zend_class_entry ce;
|
zend_class_entry ce;
|
||||||
|
|
||||||
INIT_CLASS_ENTRY(ce, "Closure", closure_functions);
|
INIT_CLASS_ENTRY(ce, "Closure", NULL);
|
||||||
zend_ce_closure = zend_register_internal_class(&ce TSRMLS_CC);
|
zend_ce_closure = zend_register_internal_class(&ce TSRMLS_CC);
|
||||||
zend_ce_closure->ce_flags |= ZEND_ACC_FINAL_CLASS;
|
zend_ce_closure->ce_flags |= ZEND_ACC_FINAL_CLASS;
|
||||||
zend_ce_closure->create_object = zend_closure_new;
|
zend_ce_closure->create_object = zend_closure_new;
|
||||||
|
|
|
@ -153,6 +153,8 @@ typedef struct _zend_try_catch_element {
|
||||||
|
|
||||||
#define ZEND_ACC_CLOSURE 0x100000
|
#define ZEND_ACC_CLOSURE 0x100000
|
||||||
|
|
||||||
|
/* function flag for internal user call handlers __call, __callstatic */
|
||||||
|
#define ZEND_ACC_CALL_VIA_HANDLER 0x200000
|
||||||
|
|
||||||
char *zend_visibility_string(zend_uint fn_flags);
|
char *zend_visibility_string(zend_uint fn_flags);
|
||||||
|
|
||||||
|
|
|
@ -685,15 +685,8 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
|
||||||
zend_class_entry *current_called_scope;
|
zend_class_entry *current_called_scope;
|
||||||
zend_class_entry *calling_scope = NULL;
|
zend_class_entry *calling_scope = NULL;
|
||||||
zend_class_entry *called_scope = NULL;
|
zend_class_entry *called_scope = NULL;
|
||||||
zend_class_entry *check_scope_or_static = NULL;
|
|
||||||
zval *current_this;
|
zval *current_this;
|
||||||
zend_execute_data execute_data;
|
zend_execute_data execute_data;
|
||||||
zval *method_name;
|
|
||||||
zval *params_array;
|
|
||||||
int call_via_handler = 0;
|
|
||||||
unsigned int clen;
|
|
||||||
int fname_len;
|
|
||||||
char *colon, *fname, *cname, *lcname;
|
|
||||||
|
|
||||||
*fci->retval_ptr_ptr = NULL;
|
*fci->retval_ptr_ptr = NULL;
|
||||||
|
|
||||||
|
@ -728,261 +721,40 @@ 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) {
|
||||||
if (Z_TYPE_P(fci->function_name) == IS_ARRAY) { /* assume array($obj, $name) couple */
|
zend_fcall_info_cache fci_cache_local;
|
||||||
zval **tmp_object_ptr, **tmp_real_function_name;
|
char *callable_name;
|
||||||
|
char *error = NULL;
|
||||||
|
|
||||||
if (zend_hash_index_find(Z_ARRVAL_P(fci->function_name), 0, (void **) &tmp_object_ptr) == FAILURE) {
|
if (!fci_cache) {
|
||||||
return FAILURE;
|
fci_cache = &fci_cache_local;
|
||||||
}
|
|
||||||
if (zend_hash_index_find(Z_ARRVAL_P(fci->function_name), 1, (void **) &tmp_real_function_name) == FAILURE) {
|
|
||||||
return FAILURE;
|
|
||||||
}
|
|
||||||
fci->function_name = *tmp_real_function_name;
|
|
||||||
SEPARATE_ZVAL_IF_NOT_REF(tmp_object_ptr);
|
|
||||||
fci->object_pp = tmp_object_ptr;
|
|
||||||
Z_SET_ISREF_PP(fci->object_pp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fci->object_pp && !*fci->object_pp) {
|
if (!zend_is_callable_ex(fci->function_name, fci->object_pp, IS_CALLABLE_CHECK_SILENT, &callable_name, NULL, fci_cache, &error TSRMLS_CC)) {
|
||||||
fci->object_pp = NULL;
|
if (error) {
|
||||||
}
|
zend_error(E_WARNING, "Invalid callback %s, %s", callable_name, error);
|
||||||
|
efree(error);
|
||||||
if (fci->object_pp) {
|
|
||||||
if (Z_TYPE_PP(fci->object_pp) == IS_OBJECT
|
|
||||||
&& (!EG(objects_store).object_buckets || !EG(objects_store).object_buckets[Z_OBJ_HANDLE_PP(fci->object_pp)].valid)) {
|
|
||||||
return FAILURE;
|
|
||||||
}
|
}
|
||||||
/* TBI!! new object handlers */
|
efree(callable_name);
|
||||||
if (Z_TYPE_PP(fci->object_pp) == IS_OBJECT) {
|
|
||||||
if (!IS_ZEND_STD_OBJECT(**fci->object_pp)) {
|
|
||||||
zend_error(E_WARNING, "Cannot use call_user_function on objects without a class entry");
|
|
||||||
return FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
calling_scope = called_scope = Z_OBJCE_PP(fci->object_pp);
|
|
||||||
fci->function_table = &calling_scope->function_table;
|
|
||||||
EX(object) = *fci->object_pp;
|
|
||||||
} else if (Z_TYPE_PP(fci->object_pp) == IS_STRING) {
|
|
||||||
zend_class_entry **ce;
|
|
||||||
int found = FAILURE;
|
|
||||||
|
|
||||||
if (strcmp(Z_STRVAL_PP(fci->object_pp), "self") == 0) {
|
|
||||||
if (!EG(active_op_array) || !EG(active_op_array)->scope) {
|
|
||||||
zend_error(E_ERROR, "Cannot access self:: when no class scope is active");
|
|
||||||
}
|
|
||||||
ce = &(EG(active_op_array)->scope);
|
|
||||||
found = (*ce != NULL?SUCCESS:FAILURE);
|
|
||||||
fci->object_pp = EG(This)?&EG(This):NULL;
|
|
||||||
EX(object) = EG(This);
|
|
||||||
calling_scope = *ce;
|
|
||||||
called_scope = EG(called_scope) ? EG(called_scope) : calling_scope;
|
|
||||||
} else if (strcmp(Z_STRVAL_PP(fci->object_pp), "parent") == 0 && EG(active_op_array)) {
|
|
||||||
|
|
||||||
if (!EG(active_op_array) || !EG(active_op_array)->scope) {
|
|
||||||
zend_error(E_ERROR, "Cannot access parent:: when no class scope is active");
|
|
||||||
}
|
|
||||||
if (!EG(active_op_array)->scope->parent) {
|
|
||||||
zend_error(E_ERROR, "Cannot access parent:: when current class scope has no parent");
|
|
||||||
}
|
|
||||||
ce = &(EG(active_op_array)->scope->parent);
|
|
||||||
found = (*ce != NULL?SUCCESS:FAILURE);
|
|
||||||
fci->object_pp = EG(This)?&EG(This):NULL;
|
|
||||||
EX(object) = EG(This);
|
|
||||||
calling_scope = *ce;
|
|
||||||
called_scope = EG(called_scope) ? EG(called_scope) : calling_scope;
|
|
||||||
} else if (Z_STRLEN_PP(fci->object_pp) == sizeof("static") - 1 &&
|
|
||||||
!memcmp(Z_STRVAL_PP(fci->object_pp), "static", sizeof("static") - 1)
|
|
||||||
) {
|
|
||||||
if (!EG(called_scope)) {
|
|
||||||
zend_error(E_ERROR, "Cannot access static:: when no class scope is active");
|
|
||||||
}
|
|
||||||
ce = &(EG(called_scope));
|
|
||||||
found = (EG(called_scope) != NULL?SUCCESS:FAILURE);
|
|
||||||
fci->object_pp = EG(This)?&EG(This):NULL;
|
|
||||||
EX(object) = EG(This);
|
|
||||||
calling_scope = called_scope = EG(called_scope);
|
|
||||||
} else {
|
|
||||||
zend_class_entry *scope;
|
|
||||||
scope = EG(active_op_array) ? EG(active_op_array)->scope : NULL;
|
|
||||||
|
|
||||||
found = zend_lookup_class(Z_STRVAL_PP(fci->object_pp), Z_STRLEN_PP(fci->object_pp), &ce TSRMLS_CC);
|
|
||||||
if (found == FAILURE) {
|
|
||||||
zend_error(E_ERROR, "Class '%s' not found", Z_STRVAL_PP(fci->object_pp));
|
|
||||||
}
|
|
||||||
if (scope && EG(This) &&
|
|
||||||
instanceof_function(Z_OBJCE_P(EG(This)), scope TSRMLS_CC) &&
|
|
||||||
instanceof_function(scope, *ce TSRMLS_CC)) {
|
|
||||||
fci->object_pp = &EG(This);
|
|
||||||
EX(object) = EG(This);
|
|
||||||
} else {
|
|
||||||
fci->object_pp = NULL;
|
|
||||||
}
|
|
||||||
calling_scope = called_scope = *ce;
|
|
||||||
}
|
|
||||||
if (found == FAILURE)
|
|
||||||
return FAILURE;
|
|
||||||
|
|
||||||
fci->function_table = &(*ce)->function_table;
|
|
||||||
} else {
|
|
||||||
zend_error(E_NOTICE, "Non-callable array passed to zend_call_function()");
|
|
||||||
return FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fci->function_table == NULL) {
|
|
||||||
return FAILURE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Z_TYPE_P(fci->function_name) == IS_OBJECT) {
|
|
||||||
if (zend_get_closure(fci->function_name, &calling_scope, &EX(function_state).function, NULL, &fci->object_pp TSRMLS_CC) == SUCCESS) {
|
|
||||||
called_scope = calling_scope;
|
|
||||||
goto init_fci_cache;
|
|
||||||
}
|
|
||||||
} else if (Z_TYPE_P(fci->function_name) != IS_STRING) {
|
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
} else if (error) {
|
||||||
|
/* Capitalize the first latter of the error message */
|
||||||
fname = Z_STRVAL_P(fci->function_name);
|
if (error[0] >= 'a' && error[0] <= 'z') {
|
||||||
fname_len = Z_STRLEN_P(fci->function_name);
|
error[0] += ('A' - 'a');
|
||||||
if (fname[0] == ':' && fname[1] == ':') {
|
|
||||||
fname += 2;
|
|
||||||
fname_len -=2;
|
|
||||||
}
|
|
||||||
EX(function_state).function = NULL;
|
|
||||||
lcname = zend_str_tolower_dup(fname, fname_len);
|
|
||||||
|
|
||||||
if (!fci->object_pp &&
|
|
||||||
zend_hash_find(fci->function_table, lcname, fname_len + 1, (void **)&EX(function_state).function) == SUCCESS
|
|
||||||
) {
|
|
||||||
efree(lcname);
|
|
||||||
} else {
|
|
||||||
efree(lcname);
|
|
||||||
|
|
||||||
cname = fname;
|
|
||||||
|
|
||||||
if ((colon = zend_memrchr(fname, ':', fname_len)) != NULL &&
|
|
||||||
colon > fname &&
|
|
||||||
*(colon - 1) == ':'
|
|
||||||
) {
|
|
||||||
zend_class_entry **pce, *ce_child = NULL;
|
|
||||||
|
|
||||||
clen = colon - fname - 1;
|
|
||||||
fname_len -= (clen + 2);
|
|
||||||
fname = colon + 1;
|
|
||||||
|
|
||||||
lcname = zend_str_tolower_dup(cname, clen);
|
|
||||||
/* caution: lcname is not '\0' terminated */
|
|
||||||
if (clen == sizeof("self") - 1 &&
|
|
||||||
memcmp(lcname, "self", sizeof("self") - 1) == 0
|
|
||||||
) {
|
|
||||||
if (!EG(active_op_array) || !EG(active_op_array)->scope) {
|
|
||||||
zend_error(E_ERROR, "Cannot access self:: when no class scope is active");
|
|
||||||
}
|
|
||||||
ce_child = EG(active_op_array) ? EG(active_op_array)->scope : NULL;
|
|
||||||
called_scope = EG(called_scope) ? EG(called_scope) : ce_child;
|
|
||||||
} else if (clen == sizeof("parent") - 1 &&
|
|
||||||
memcmp(lcname, "parent", sizeof("parent") - 1) == 0
|
|
||||||
) {
|
|
||||||
if (!EG(active_op_array) || !EG(active_op_array)->scope) {
|
|
||||||
zend_error(E_ERROR, "Cannot access parent:: when no class scope is active");
|
|
||||||
}
|
|
||||||
if (!EG(active_op_array)->scope->parent) {
|
|
||||||
zend_error(E_ERROR, "Cannot access parent:: when current class scope has no parent");
|
|
||||||
}
|
|
||||||
ce_child = EG(active_op_array) && EG(active_op_array)->scope ? EG(active_op_array)->scope->parent : NULL;
|
|
||||||
called_scope = EG(called_scope) ? EG(called_scope) : ce_child;
|
|
||||||
} else if (clen == sizeof("static") - 1 &&
|
|
||||||
memcmp(lcname, "static", sizeof("static") - 1)
|
|
||||||
) {
|
|
||||||
if (!EG(called_scope)) {
|
|
||||||
zend_error(E_ERROR, "Cannot access static:: when no class scope is active");
|
|
||||||
}
|
|
||||||
called_scope = ce_child = EG(called_scope);
|
|
||||||
} else if (zend_lookup_class(lcname, clen, &pce TSRMLS_CC) == SUCCESS) {
|
|
||||||
called_scope = ce_child = *pce;
|
|
||||||
}
|
|
||||||
efree(lcname);
|
|
||||||
|
|
||||||
if (!ce_child) {
|
|
||||||
zend_error(E_ERROR, "Cannot call method %s() or method does not exist", Z_STRVAL_P(fci->function_name));
|
|
||||||
return FAILURE;
|
|
||||||
}
|
|
||||||
check_scope_or_static = calling_scope;
|
|
||||||
fci->function_table = &ce_child->function_table;
|
|
||||||
calling_scope = ce_child;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fci->object_pp) {
|
|
||||||
if (Z_OBJ_HT_PP(fci->object_pp)->get_method == NULL) {
|
|
||||||
zend_error(E_ERROR, "Object does not support method calls");
|
|
||||||
}
|
|
||||||
EX(function_state).function =
|
|
||||||
Z_OBJ_HT_PP(fci->object_pp)->get_method(fci->object_pp, fname, fname_len TSRMLS_CC);
|
|
||||||
if (EX(function_state).function && calling_scope != EX(function_state).function->common.scope) {
|
|
||||||
char *function_name_lc = zend_str_tolower_dup(fname, fname_len);
|
|
||||||
if (zend_hash_find(&calling_scope->function_table, function_name_lc, fname_len + 1, (void **) &EX(function_state).function) == FAILURE) {
|
|
||||||
efree(function_name_lc);
|
|
||||||
zend_error(E_ERROR, "Cannot call method %s::%s() or method does not exist", calling_scope->name, fname);
|
|
||||||
}
|
|
||||||
efree(function_name_lc);
|
|
||||||
}
|
|
||||||
} else if (calling_scope) {
|
|
||||||
if (calling_scope->get_static_method) {
|
|
||||||
EX(function_state).function = calling_scope->get_static_method(calling_scope, fname, fname_len TSRMLS_CC);
|
|
||||||
} else {
|
|
||||||
EX(function_state).function = zend_std_get_static_method(calling_scope, fname, fname_len TSRMLS_CC);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (((zend_internal_function*)EX(function_state).function)->handler == zend_std_call_user_call) {
|
|
||||||
fci->object_pp = &EG(This);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (check_scope_or_static && EX(function_state).function
|
|
||||||
&& !(EX(function_state).function->common.fn_flags & ZEND_ACC_STATIC)
|
|
||||||
&& !instanceof_function(check_scope_or_static, calling_scope TSRMLS_CC)) {
|
|
||||||
zend_error(E_ERROR, "Cannot call method %s() of class %s which is not a derived from %s", Z_STRVAL_P(fci->function_name), calling_scope->name, check_scope_or_static->name);
|
|
||||||
return FAILURE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
zend_error(E_STRICT, "%s", error);
|
||||||
|
efree(error);
|
||||||
}
|
}
|
||||||
|
efree(callable_name);
|
||||||
|
}
|
||||||
|
|
||||||
if (EX(function_state).function == NULL) {
|
EX(function_state).function = fci_cache->function_handler;
|
||||||
/* try calling __call */
|
calling_scope = fci_cache->calling_scope;
|
||||||
if (calling_scope && calling_scope->__call) {
|
called_scope = fci_cache->called_scope;
|
||||||
EX(function_state).function = calling_scope->__call;
|
fci->object_pp = fci_cache->object_pp;
|
||||||
/* prepare params */
|
EX(object) = fci->object_pp ? *fci->object_pp : NULL;
|
||||||
ALLOC_INIT_ZVAL(method_name);
|
if (fci->object_pp && *fci->object_pp && Z_TYPE_PP(fci->object_pp) == IS_OBJECT &&
|
||||||
ZVAL_STRINGL(method_name, fname, fname_len, 0);
|
(!EG(objects_store).object_buckets || !EG(objects_store).object_buckets[Z_OBJ_HANDLE_PP(fci->object_pp)].valid)) {
|
||||||
|
return FAILURE;
|
||||||
ALLOC_INIT_ZVAL(params_array);
|
|
||||||
array_init(params_array);
|
|
||||||
call_via_handler = 1;
|
|
||||||
} else {
|
|
||||||
return FAILURE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
init_fci_cache:
|
|
||||||
if (fci_cache &&
|
|
||||||
(EX(function_state).function->type != ZEND_INTERNAL_FUNCTION ||
|
|
||||||
((zend_internal_function*)EX(function_state).function)->handler != zend_std_call_user_call)
|
|
||||||
) {
|
|
||||||
fci_cache->function_handler = EX(function_state).function;
|
|
||||||
fci_cache->object_pp = fci->object_pp;
|
|
||||||
fci_cache->calling_scope = calling_scope;
|
|
||||||
fci_cache->called_scope = called_scope;
|
|
||||||
fci_cache->initialized = 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
EX(function_state).function = fci_cache->function_handler;
|
|
||||||
calling_scope = fci_cache->calling_scope;
|
|
||||||
called_scope = fci_cache->called_scope;
|
|
||||||
fci->object_pp = fci_cache->object_pp;
|
|
||||||
EX(object) = fci->object_pp ? *fci->object_pp : NULL;
|
|
||||||
if (fci->object_pp && *fci->object_pp && Z_TYPE_PP(fci->object_pp) == IS_OBJECT
|
|
||||||
&& (!EG(objects_store).object_buckets || !EG(objects_store).object_buckets[Z_OBJ_HANDLE_PP(fci->object_pp)].valid)) {
|
|
||||||
return FAILURE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EX(function_state).function->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) {
|
if (EX(function_state).function->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) {
|
||||||
|
@ -997,11 +769,7 @@ init_fci_cache:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (call_via_handler) {
|
ZEND_VM_STACK_GROW_IF_NEEDED(fci->param_count + 1);
|
||||||
ZEND_VM_STACK_GROW_IF_NEEDED(2 + 1);
|
|
||||||
} else {
|
|
||||||
ZEND_VM_STACK_GROW_IF_NEEDED(fci->param_count + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i=0; i<fci->param_count; i++) {
|
for (i=0; i<fci->param_count; i++) {
|
||||||
zval *param;
|
zval *param;
|
||||||
|
@ -1019,10 +787,6 @@ init_fci_cache:
|
||||||
zend_vm_stack_clear_multiple(TSRMLS_C);
|
zend_vm_stack_clear_multiple(TSRMLS_C);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (call_via_handler) {
|
|
||||||
zval_ptr_dtor(&method_name);
|
|
||||||
zval_ptr_dtor(¶ms_array);
|
|
||||||
}
|
|
||||||
zend_error(E_WARNING, "Parameter %d to %s%s%s() expected to be a reference, value given",
|
zend_error(E_WARNING, "Parameter %d to %s%s%s() expected to be a reference, value given",
|
||||||
i+1,
|
i+1,
|
||||||
EX(function_state).function->common.scope ? EX(function_state).function->common.scope->name : "",
|
EX(function_state).function->common.scope ? EX(function_state).function->common.scope->name : "",
|
||||||
|
@ -1049,17 +813,7 @@ init_fci_cache:
|
||||||
*param = **(fci->params[i]);
|
*param = **(fci->params[i]);
|
||||||
INIT_PZVAL(param);
|
INIT_PZVAL(param);
|
||||||
}
|
}
|
||||||
if (call_via_handler) {
|
zend_vm_stack_push_nocheck(param TSRMLS_CC);
|
||||||
add_next_index_zval(params_array, param);
|
|
||||||
} else {
|
|
||||||
zend_vm_stack_push_nocheck(param TSRMLS_CC);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (call_via_handler) {
|
|
||||||
zend_vm_stack_push_nocheck(method_name TSRMLS_CC);
|
|
||||||
zend_vm_stack_push_nocheck(params_array TSRMLS_CC);
|
|
||||||
fci->param_count = 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EX(function_state).arguments = zend_vm_stack_top(TSRMLS_C);
|
EX(function_state).arguments = zend_vm_stack_top(TSRMLS_C);
|
||||||
|
@ -1097,19 +851,6 @@ init_fci_cache:
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
EG(This) = NULL;
|
EG(This) = NULL;
|
||||||
if (calling_scope && !(EX(function_state).function->common.fn_flags & ZEND_ACC_STATIC)) {
|
|
||||||
int severity;
|
|
||||||
char *verb;
|
|
||||||
if (EX(function_state).function->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
|
|
||||||
severity = E_STRICT;
|
|
||||||
verb = "should not";
|
|
||||||
} else {
|
|
||||||
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
|
|
||||||
severity = E_ERROR;
|
|
||||||
verb = "cannot";
|
|
||||||
}
|
|
||||||
zend_error(severity, "Non-static method %s::%s() %s be called statically", calling_scope->name, EX(function_state).function->common.function_name, verb);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EX(prev_execute_data) = EG(current_execute_data);
|
EX(prev_execute_data) = EG(current_execute_data);
|
||||||
|
@ -1146,6 +887,8 @@ init_fci_cache:
|
||||||
EG(return_value_ptr_ptr)=original_return_value;
|
EG(return_value_ptr_ptr)=original_return_value;
|
||||||
EG(opline_ptr) = original_opline_ptr;
|
EG(opline_ptr) = original_opline_ptr;
|
||||||
} else {
|
} else {
|
||||||
|
int call_via_handler = (EX(function_state).function->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0;
|
||||||
|
|
||||||
ALLOC_INIT_ZVAL(*fci->retval_ptr_ptr);
|
ALLOC_INIT_ZVAL(*fci->retval_ptr_ptr);
|
||||||
if (EX(function_state).function->common.scope) {
|
if (EX(function_state).function->common.scope) {
|
||||||
EG(scope) = EX(function_state).function->common.scope;
|
EG(scope) = EX(function_state).function->common.scope;
|
||||||
|
@ -1161,12 +904,13 @@ init_fci_cache:
|
||||||
zval_ptr_dtor(fci->retval_ptr_ptr);
|
zval_ptr_dtor(fci->retval_ptr_ptr);
|
||||||
*fci->retval_ptr_ptr = NULL;
|
*fci->retval_ptr_ptr = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (call_via_handler) {
|
||||||
|
/* We must re-initialize function again */
|
||||||
|
fci_cache->initialized = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
zend_vm_stack_clear_multiple(TSRMLS_C);
|
zend_vm_stack_clear_multiple(TSRMLS_C);
|
||||||
if (call_via_handler) {
|
|
||||||
zval_ptr_dtor(&method_name);
|
|
||||||
zval_ptr_dtor(¶ms_array);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (EG(This)) {
|
if (EG(This)) {
|
||||||
zval_ptr_dtor(&EG(This));
|
zval_ptr_dtor(&EG(This));
|
||||||
|
|
|
@ -793,7 +793,7 @@ static union _zend_function *zend_std_get_method(zval **object_ptr, char *method
|
||||||
call_user_call->arg_info = NULL;
|
call_user_call->arg_info = NULL;
|
||||||
call_user_call->num_args = 0;
|
call_user_call->num_args = 0;
|
||||||
call_user_call->scope = zobj->ce;
|
call_user_call->scope = zobj->ce;
|
||||||
call_user_call->fn_flags = 0;
|
call_user_call->fn_flags = ZEND_ACC_CALL_VIA_HANDLER;
|
||||||
call_user_call->function_name = estrndup(method_name, method_len);
|
call_user_call->function_name = estrndup(method_name, method_len);
|
||||||
call_user_call->pass_rest_by_reference = 0;
|
call_user_call->pass_rest_by_reference = 0;
|
||||||
call_user_call->return_reference = ZEND_RETURN_VALUE;
|
call_user_call->return_reference = ZEND_RETURN_VALUE;
|
||||||
|
@ -919,7 +919,7 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, char *f
|
||||||
call_user_call->arg_info = NULL;
|
call_user_call->arg_info = NULL;
|
||||||
call_user_call->num_args = 0;
|
call_user_call->num_args = 0;
|
||||||
call_user_call->scope = ce;
|
call_user_call->scope = ce;
|
||||||
call_user_call->fn_flags = 0;
|
call_user_call->fn_flags = ZEND_ACC_CALL_VIA_HANDLER;
|
||||||
call_user_call->function_name = estrndup(function_name_strval, function_name_strlen);
|
call_user_call->function_name = estrndup(function_name_strval, function_name_strlen);
|
||||||
call_user_call->pass_rest_by_reference = 0;
|
call_user_call->pass_rest_by_reference = 0;
|
||||||
call_user_call->return_reference = ZEND_RETURN_VALUE;
|
call_user_call->return_reference = ZEND_RETURN_VALUE;
|
||||||
|
@ -934,14 +934,14 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, char *f
|
||||||
callstatic_user_call->arg_info = NULL;
|
callstatic_user_call->arg_info = NULL;
|
||||||
callstatic_user_call->num_args = 0;
|
callstatic_user_call->num_args = 0;
|
||||||
callstatic_user_call->scope = ce;
|
callstatic_user_call->scope = ce;
|
||||||
callstatic_user_call->fn_flags = ZEND_ACC_STATIC | ZEND_ACC_PUBLIC;
|
callstatic_user_call->fn_flags = ZEND_ACC_STATIC | ZEND_ACC_PUBLIC | ZEND_ACC_CALL_VIA_HANDLER;
|
||||||
callstatic_user_call->function_name = estrndup(function_name_strval, function_name_strlen);
|
callstatic_user_call->function_name = estrndup(function_name_strval, function_name_strlen);
|
||||||
callstatic_user_call->pass_rest_by_reference = 0;
|
callstatic_user_call->pass_rest_by_reference = 0;
|
||||||
callstatic_user_call->return_reference = ZEND_RETURN_VALUE;
|
callstatic_user_call->return_reference = ZEND_RETURN_VALUE;
|
||||||
|
|
||||||
return (zend_function *)callstatic_user_call;
|
return (zend_function *)callstatic_user_call;
|
||||||
} else {
|
} else {
|
||||||
zend_error(E_ERROR, "Call to undefined method %s::%s()", ce->name ? ce->name : "", function_name_strval);
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
efree(lc_function_name);
|
efree(lc_function_name);
|
||||||
|
|
|
@ -1978,6 +1978,9 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMP|VAR|UNUS
|
||||||
} else {
|
} else {
|
||||||
EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
|
EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
|
||||||
}
|
}
|
||||||
|
if (!EX(fbc)) {
|
||||||
|
zend_error(E_ERROR, "Call to undefined method %s::%s()", ce->name, function_name_strval);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (OP2_TYPE != IS_CONST) {
|
if (OP2_TYPE != IS_CONST) {
|
||||||
|
|
|
@ -2641,6 +2641,9 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER(
|
||||||
} else {
|
} else {
|
||||||
EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
|
EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
|
||||||
}
|
}
|
||||||
|
if (!EX(fbc)) {
|
||||||
|
zend_error(E_ERROR, "Call to undefined method %s::%s()", ce->name, function_name_strval);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_CONST != IS_CONST) {
|
if (IS_CONST != IS_CONST) {
|
||||||
|
@ -3234,6 +3237,9 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_HANDLER(ZE
|
||||||
} else {
|
} else {
|
||||||
EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
|
EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
|
||||||
}
|
}
|
||||||
|
if (!EX(fbc)) {
|
||||||
|
zend_error(E_ERROR, "Call to undefined method %s::%s()", ce->name, function_name_strval);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_TMP_VAR != IS_CONST) {
|
if (IS_TMP_VAR != IS_CONST) {
|
||||||
|
@ -3707,6 +3713,9 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_VAR_HANDLER(ZE
|
||||||
} else {
|
} else {
|
||||||
EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
|
EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
|
||||||
}
|
}
|
||||||
|
if (!EX(fbc)) {
|
||||||
|
zend_error(E_ERROR, "Call to undefined method %s::%s()", ce->name, function_name_strval);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_VAR != IS_CONST) {
|
if (IS_VAR != IS_CONST) {
|
||||||
|
@ -3936,6 +3945,9 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_HANDLER
|
||||||
} else {
|
} else {
|
||||||
EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
|
EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
|
||||||
}
|
}
|
||||||
|
if (!EX(fbc)) {
|
||||||
|
zend_error(E_ERROR, "Call to undefined method %s::%s()", ce->name, function_name_strval);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_UNUSED != IS_CONST) {
|
if (IS_UNUSED != IS_CONST) {
|
||||||
|
@ -4377,6 +4389,9 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_HANDLER(ZEN
|
||||||
} else {
|
} else {
|
||||||
EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
|
EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
|
||||||
}
|
}
|
||||||
|
if (!EX(fbc)) {
|
||||||
|
zend_error(E_ERROR, "Call to undefined method %s::%s()", ce->name, function_name_strval);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_CV != IS_CONST) {
|
if (IS_CV != IS_CONST) {
|
||||||
|
@ -10320,6 +10335,9 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZE
|
||||||
} else {
|
} else {
|
||||||
EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
|
EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
|
||||||
}
|
}
|
||||||
|
if (!EX(fbc)) {
|
||||||
|
zend_error(E_ERROR, "Call to undefined method %s::%s()", ce->name, function_name_strval);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_CONST != IS_CONST) {
|
if (IS_CONST != IS_CONST) {
|
||||||
|
@ -12157,6 +12175,9 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND
|
||||||
} else {
|
} else {
|
||||||
EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
|
EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
|
||||||
}
|
}
|
||||||
|
if (!EX(fbc)) {
|
||||||
|
zend_error(E_ERROR, "Call to undefined method %s::%s()", ce->name, function_name_strval);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_TMP_VAR != IS_CONST) {
|
if (IS_TMP_VAR != IS_CONST) {
|
||||||
|
@ -13970,6 +13991,9 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND
|
||||||
} else {
|
} else {
|
||||||
EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
|
EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
|
||||||
}
|
}
|
||||||
|
if (!EX(fbc)) {
|
||||||
|
zend_error(E_ERROR, "Call to undefined method %s::%s()", ce->name, function_name_strval);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_VAR != IS_CONST) {
|
if (IS_VAR != IS_CONST) {
|
||||||
|
@ -14880,6 +14904,9 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_HANDLER(Z
|
||||||
} else {
|
} else {
|
||||||
EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
|
EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
|
||||||
}
|
}
|
||||||
|
if (!EX(fbc)) {
|
||||||
|
zend_error(E_ERROR, "Call to undefined method %s::%s()", ce->name, function_name_strval);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_UNUSED != IS_CONST) {
|
if (IS_UNUSED != IS_CONST) {
|
||||||
|
@ -16394,6 +16421,9 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_
|
||||||
} else {
|
} else {
|
||||||
EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
|
EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
|
||||||
}
|
}
|
||||||
|
if (!EX(fbc)) {
|
||||||
|
zend_error(E_ERROR, "Call to undefined method %s::%s()", ce->name, function_name_strval);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_CV != IS_CONST) {
|
if (IS_CV != IS_CONST) {
|
||||||
|
|
|
@ -1258,7 +1258,7 @@ static void _reflection_export(INTERNAL_FUNCTION_PARAMETERS, zend_class_entry *c
|
||||||
params[0] = &reflector_ptr;
|
params[0] = &reflector_ptr;
|
||||||
params[1] = &output_ptr;
|
params[1] = &output_ptr;
|
||||||
|
|
||||||
ZVAL_STRINGL(&fname, "export", sizeof("export") - 1, 0);
|
ZVAL_STRINGL(&fname, "reflection::export", sizeof("reflection::export") - 1, 0);
|
||||||
fci.function_table = &reflection_ptr->function_table;
|
fci.function_table = &reflection_ptr->function_table;
|
||||||
fci.function_name = &fname;
|
fci.function_name = &fname;
|
||||||
fci.object_pp = NULL;
|
fci.object_pp = NULL;
|
||||||
|
|
|
@ -451,7 +451,7 @@ PHP_FUNCTION(spl_autoload_register)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!zend_is_callable_ex(zcallable, IS_CALLABLE_STRICT, &func_name, &func_name_len, &fcc, &error TSRMLS_CC)) {
|
if (!zend_is_callable_ex(zcallable, NULL, IS_CALLABLE_STRICT, &func_name, &func_name_len, &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_pp;
|
obj_ptr = fcc.object_pp;
|
||||||
|
@ -573,7 +573,7 @@ PHP_FUNCTION(spl_autoload_unregister)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!zend_is_callable_ex(zcallable, 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, &func_name_len, &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);
|
||||||
|
|
|
@ -57,7 +57,7 @@ foreach($funcs as $idx => $func)
|
||||||
<?php exit(0); ?>
|
<?php exit(0); ?>
|
||||||
--EXPECTF--
|
--EXPECTF--
|
||||||
string(22) "MyAutoLoader::notExist"
|
string(22) "MyAutoLoader::notExist"
|
||||||
Function 'MyAutoLoader::notExist' not found (class 'MyAutoLoader' does not have a method 'notexist')
|
Function 'MyAutoLoader::notExist' not found (class 'MyAutoLoader' does not have a method 'notExist')
|
||||||
|
|
||||||
string(22) "MyAutoLoader::noAccess"
|
string(22) "MyAutoLoader::noAccess"
|
||||||
Function 'MyAutoLoader::noAccess' not callable (cannot access protected method MyAutoLoader::noAccess())
|
Function 'MyAutoLoader::noAccess' not callable (cannot access protected method MyAutoLoader::noAccess())
|
||||||
|
@ -74,7 +74,7 @@ array(2) {
|
||||||
[1]=>
|
[1]=>
|
||||||
string(8) "notExist"
|
string(8) "notExist"
|
||||||
}
|
}
|
||||||
Passed array does not specify an existing static method (class 'MyAutoLoader' does not have a method 'notexist')
|
Passed array does not specify an existing static method (class 'MyAutoLoader' does not have a method 'notExist')
|
||||||
|
|
||||||
array(2) {
|
array(2) {
|
||||||
[0]=>
|
[0]=>
|
||||||
|
@ -107,7 +107,7 @@ array(2) {
|
||||||
[1]=>
|
[1]=>
|
||||||
string(8) "notExist"
|
string(8) "notExist"
|
||||||
}
|
}
|
||||||
Passed array does not specify an existing method (class 'MyAutoLoader' does not have a method 'notexist')
|
Passed array does not specify an existing method (class 'MyAutoLoader' does not have a method 'notExist')
|
||||||
|
|
||||||
array(2) {
|
array(2) {
|
||||||
[0]=>
|
[0]=>
|
||||||
|
|
|
@ -70,7 +70,7 @@ class ChildClass extends AbstractClass
|
||||||
{
|
{
|
||||||
private $var3;
|
private $var3;
|
||||||
public function emptyFunction() {
|
public function emptyFunction() {
|
||||||
echo "defined in child";
|
echo "defined in child\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
test(array('ChildClass', 'emptyFunction'), array(1, 2));
|
test(array('ChildClass', 'emptyFunction'), array(1, 2));
|
||||||
|
@ -80,7 +80,7 @@ class FinalClass
|
||||||
{
|
{
|
||||||
private $var4;
|
private $var4;
|
||||||
final function finalMethod() {
|
final function finalMethod() {
|
||||||
echo "This function can't be overloaded";
|
echo "This function can't be overloaded\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
test(array('FinalClass', 'finalMethod'), array(1, 2));
|
test(array('FinalClass', 'finalMethod'), array(1, 2));
|
||||||
|
@ -128,10 +128,6 @@ test(array('InterClass', 'square'), array(1, 2));
|
||||||
SimpleClass::square
|
SimpleClass::square
|
||||||
|
|
||||||
Strict Standards: array_map() expects parameter 1 to be a valid callback, non-static method SimpleClass::square() should not be called statically in %sarray_map_object1.php on line %d
|
Strict Standards: array_map() expects parameter 1 to be a valid callback, non-static method SimpleClass::square() should not be called statically in %sarray_map_object1.php on line %d
|
||||||
|
|
||||||
Strict Standards: Non-static method SimpleClass::square() should not be called statically in %sarray_map_object1.php on line %d
|
|
||||||
|
|
||||||
Strict Standards: Non-static method SimpleClass::square() should not be called statically in %sarray_map_object1.php on line %d
|
|
||||||
array(2) {
|
array(2) {
|
||||||
[0]=>
|
[0]=>
|
||||||
int(1)
|
int(1)
|
||||||
|
@ -161,11 +157,9 @@ NULL
|
||||||
ChildClass::emptyFunction
|
ChildClass::emptyFunction
|
||||||
|
|
||||||
Strict Standards: array_map() expects parameter 1 to be a valid callback, non-static method ChildClass::emptyFunction() should not be called statically in %sarray_map_object1.php on line %d
|
Strict Standards: array_map() expects parameter 1 to be a valid callback, non-static method ChildClass::emptyFunction() should not be called statically in %sarray_map_object1.php on line %d
|
||||||
|
|
||||||
Strict Standards: Non-static method ChildClass::emptyFunction() should not be called statically in %sarray_map_object1.php on line %d
|
|
||||||
defined in child
|
defined in child
|
||||||
Strict Standards: Non-static method ChildClass::emptyFunction() should not be called statically in %sarray_map_object1.php on line %d
|
defined in child
|
||||||
defined in childarray(2) {
|
array(2) {
|
||||||
[0]=>
|
[0]=>
|
||||||
NULL
|
NULL
|
||||||
[1]=>
|
[1]=>
|
||||||
|
@ -176,11 +170,9 @@ defined in childarray(2) {
|
||||||
FinalClass::finalMethod
|
FinalClass::finalMethod
|
||||||
|
|
||||||
Strict Standards: array_map() expects parameter 1 to be a valid callback, non-static method FinalClass::finalMethod() should not be called statically in %sarray_map_object1.php on line %d
|
Strict Standards: array_map() expects parameter 1 to be a valid callback, non-static method FinalClass::finalMethod() should not be called statically in %sarray_map_object1.php on line %d
|
||||||
|
|
||||||
Strict Standards: Non-static method FinalClass::finalMethod() should not be called statically in %sarray_map_object1.php on line %d
|
|
||||||
This function can't be overloaded
|
This function can't be overloaded
|
||||||
Strict Standards: Non-static method FinalClass::finalMethod() should not be called statically in %sarray_map_object1.php on line %d
|
This function can't be overloaded
|
||||||
This function can't be overloadedarray(2) {
|
array(2) {
|
||||||
[0]=>
|
[0]=>
|
||||||
NULL
|
NULL
|
||||||
[1]=>
|
[1]=>
|
||||||
|
|
|
@ -74,7 +74,7 @@ array(3) {
|
||||||
}
|
}
|
||||||
-- accessing child method from parent class --
|
-- accessing child method from parent class --
|
||||||
|
|
||||||
Warning: array_map() expects parameter 1 to be a valid callback, class 'ParentClass' does not have a method 'staticchild' in %s on line %d
|
Warning: array_map() expects parameter 1 to be a valid callback, class 'ParentClass' does not have a method 'staticChild' in %s on line %d
|
||||||
NULL
|
NULL
|
||||||
-- accessing parent method using child class object --
|
-- accessing parent method using child class object --
|
||||||
array(3) {
|
array(3) {
|
||||||
|
@ -87,6 +87,6 @@ array(3) {
|
||||||
}
|
}
|
||||||
-- accessing child method using parent class object --
|
-- accessing child method using parent class object --
|
||||||
|
|
||||||
Warning: array_map() expects parameter 1 to be a valid callback, class 'ParentClass' does not have a method 'staticchild' in %s on line %d
|
Warning: array_map() expects parameter 1 to be a valid callback, class 'ParentClass' does not have a method 'staticChild' in %s on line %d
|
||||||
NULL
|
NULL
|
||||||
Done
|
Done
|
||||||
|
|
|
@ -77,16 +77,8 @@ new Derived_6('6');
|
||||||
--EXPECTF--
|
--EXPECTF--
|
||||||
Base::__construct(1)
|
Base::__construct(1)
|
||||||
Base::__construct(2)
|
Base::__construct(2)
|
||||||
|
|
||||||
Strict Standards: call_user_func_array() expects parameter 1 to be a valid callback, non-static method Base::__construct() cannot be called statically, assuming $this from compatible context Derived_%d in %s on line %d
|
|
||||||
Base::__construct(3)
|
Base::__construct(3)
|
||||||
|
|
||||||
Strict Standards: call_user_func_array() expects parameter 1 to be a valid callback, non-static method Base::__construct() cannot be called statically, assuming $this from compatible context Derived_%d in %s on line %d
|
|
||||||
Base::__construct(4)
|
Base::__construct(4)
|
||||||
|
|
||||||
Strict Standards: call_user_func_array() expects parameter 1 to be a valid callback, non-static method Base::__construct() cannot be called statically, assuming $this from compatible context Derived_%d in %s on line %d
|
|
||||||
Base::__construct(5)
|
Base::__construct(5)
|
||||||
|
|
||||||
Strict Standards: call_user_func_array() expects parameter 1 to be a valid callback, non-static method Base::__construct() cannot be called statically, assuming $this from compatible context Derived_%d in %s on line %d
|
|
||||||
Base::__construct(6)
|
Base::__construct(6)
|
||||||
===DONE===
|
===DONE===
|
||||||
|
|
|
@ -97,12 +97,8 @@ B|who2
|
||||||
A
|
A
|
||||||
===FOREIGN===
|
===FOREIGN===
|
||||||
parent|who
|
parent|who
|
||||||
|
|
||||||
Strict Standards: call_user_func() expects parameter 1 to be a valid callback, non-static method O::who() should not be called statically, assuming $this from compatible context P in %s on line %d
|
|
||||||
O
|
O
|
||||||
P|parent::who
|
P|parent::who
|
||||||
|
|
||||||
Strict Standards: call_user_func() expects parameter 1 to be a valid callback, non-static method O::who() should not be called statically, assuming $this from compatible context P in %s on line %d
|
|
||||||
O
|
O
|
||||||
$this|O::who
|
$this|O::who
|
||||||
O
|
O
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue