Browse Source

Fixed bug #50261 (Crash When Calling Parent Constructor with call_user_func())

experimental/5.3-FPM
Dmitry Stogov 17 years ago
parent
commit
5c56abb6e3
  1. 2
      NEWS
  2. 60
      Zend/zend_API.c

2
NEWS

@ -30,6 +30,8 @@ PHP NEWS
calling function). (Felipe)
- Fixed bug #50267 (get_browser(null) does not use HTTP_USER_AGENT). (Jani)
- Fixed bug #50266 (conflicting types for llabs). (Jani)
- Fixed bug #50261 (Crash When Calling Parent Constructor with
call_user_func()). (Dmitry)
- Fixed bug #50255 (isset() and empty() silently casts array to object).
(Felipe)
- Fixed bug #50240 (pdo_mysql.default_socket in php.ini shouldn't used

60
Zend/zend_API.c

@ -2117,7 +2117,7 @@ void module_destructor(zend_module_entry *module) /* {{{ */
#if HAVE_LIBDL
#if !(defined(NETWARE) && defined(APACHE_1_BUILD))
if (module->handle) {
DL_UNLOAD(module->handle);
// DL_UNLOAD(module->handle);
}
#endif
#endif
@ -2335,12 +2335,13 @@ ZEND_API int zend_disable_class(char *class_name, uint class_name_length TSRMLS_
}
/* }}} */
static int zend_is_callable_check_class(const char *name, int name_len, zend_fcall_info_cache *fcc, char **error TSRMLS_DC) /* {{{ */
static int zend_is_callable_check_class(const char *name, int name_len, zend_fcall_info_cache *fcc, int *strict_class, char **error TSRMLS_DC) /* {{{ */
{
int ret = 0;
zend_class_entry **pce;
char *lcname = zend_str_tolower_dup(name, name_len);
*strict_class = 0;
if (name_len == sizeof("self") - 1 &&
!memcmp(lcname, "self", sizeof("self") - 1)) {
if (!EG(scope)) {
@ -2365,6 +2366,7 @@ static int zend_is_callable_check_class(const char *name, int name_len, zend_fca
if (!fcc->object_ptr) {
fcc->object_ptr = EG(This);
}
*strict_class = 1;
ret = 1;
}
} else if (name_len == sizeof("static") - 1 &&
@ -2377,6 +2379,7 @@ static int zend_is_callable_check_class(const char *name, int name_len, zend_fca
if (!fcc->object_ptr) {
fcc->object_ptr = EG(This);
}
*strict_class = 1;
ret = 1;
}
} else if (zend_lookup_class_ex(name, name_len, 1, &pce TSRMLS_CC) == SUCCESS) {
@ -2391,6 +2394,7 @@ static int zend_is_callable_check_class(const char *name, int name_len, zend_fca
} else {
fcc->called_scope = fcc->object_ptr ? Z_OBJCE_P(fcc->object_ptr) : fcc->calling_scope;
}
*strict_class = 1;
ret = 1;
} else {
if (error) zend_spprintf(error, 0, "class '%.*s' not found", name_len, name);
@ -2401,7 +2405,7 @@ static int zend_is_callable_check_class(const char *name, int name_len, zend_fca
/* }}} */
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, int strict_class, char **error TSRMLS_DC) /* {{{ */
{
zend_class_entry *ce_org = fcc->calling_scope;
int retval = 0;
@ -2459,7 +2463,7 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca
EG(scope) = ce_org;
}
if (!zend_is_callable_check_class(Z_STRVAL_P(callable), clen, fcc, error TSRMLS_CC)) {
if (!zend_is_callable_check_class(Z_STRVAL_P(callable), clen, fcc, &strict_class, error TSRMLS_CC)) {
EG(scope) = last_scope;
return 0;
}
@ -2486,7 +2490,15 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca
}
lmname = zend_str_tolower_dup(mname, mlen);
if (zend_hash_find(ftable, lmname, mlen+1, (void**)&fcc->function_handler) == SUCCESS) {
if (strict_class &&
fcc->calling_scope &&
mlen == sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)-1 &&
!memcmp(lmname, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME))) {
fcc->function_handler = fcc->calling_scope->constructor;
if (fcc->function_handler) {
retval = 1;
}
} else if (zend_hash_find(ftable, lmname, mlen+1, (void**)&fcc->function_handler) == SUCCESS) {
retval = 1;
if ((fcc->function_handler->op_array.fn_flags & ZEND_ACC_CHANGED) &&
EG(scope) &&
@ -2520,11 +2532,36 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca
} else {
get_function_via_handler:
if (fcc->object_ptr && fcc->calling_scope == ce_org) {
if (Z_OBJ_HT_P(fcc->object_ptr)->get_method) {
if (strict_class && ce_org->__call) {
fcc->function_handler = emalloc(sizeof(zend_internal_function));
fcc->function_handler->internal_function.type = ZEND_INTERNAL_FUNCTION;
fcc->function_handler->internal_function.module = ce_org->module;
fcc->function_handler->internal_function.handler = zend_std_call_user_call;
fcc->function_handler->internal_function.arg_info = NULL;
fcc->function_handler->internal_function.num_args = 0;
fcc->function_handler->internal_function.scope = ce_org;
fcc->function_handler->internal_function.fn_flags = ZEND_ACC_CALL_VIA_HANDLER;
fcc->function_handler->internal_function.function_name = estrndup(mname, mlen);
fcc->function_handler->internal_function.pass_rest_by_reference = 0;
fcc->function_handler->internal_function.return_reference = ZEND_RETURN_VALUE;
call_via_handler = 1;
retval = 1;
} else if (Z_OBJ_HT_P(fcc->object_ptr)->get_method) {
fcc->function_handler = Z_OBJ_HT_P(fcc->object_ptr)->get_method(&fcc->object_ptr, mname, mlen TSRMLS_CC);
if (fcc->function_handler) {
retval = 1;
call_via_handler = (fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0;
if (strict_class &&
(!fcc->function_handler->common.scope ||
!instanceof_function(ce_org, fcc->function_handler->common.scope TSRMLS_CC))) {
if ((fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0) {
if (fcc->function_handler->type != ZEND_OVERLOADED_FUNCTION) {
efree(fcc->function_handler->common.function_name);
}
efree(fcc->function_handler);
}
} else {
retval = 1;
call_via_handler = (fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0;
}
}
}
} else if (fcc->calling_scope) {
@ -2680,7 +2717,7 @@ ZEND_API zend_bool zend_is_callable_ex(zval *callable, zval *object_ptr, uint ch
return 1;
}
ret = zend_is_callable_check_func(check_flags, callable, fcc, error TSRMLS_CC);
ret = zend_is_callable_check_func(check_flags, callable, fcc, 0, error TSRMLS_CC);
if (fcc == &fcc_local &&
fcc->function_handler &&
((fcc->function_handler->type == ZEND_INTERNAL_FUNCTION &&
@ -2698,6 +2735,7 @@ ZEND_API zend_bool zend_is_callable_ex(zval *callable, zval *object_ptr, uint ch
{
zval **method = NULL;
zval **obj = NULL;
int strict_class = 0;
if (zend_hash_num_elements(Z_ARRVAL_P(callable)) == 2) {
zend_hash_index_find(Z_ARRVAL_P(callable), 0, (void **) &obj);
@ -2725,7 +2763,7 @@ ZEND_API zend_bool zend_is_callable_ex(zval *callable, zval *object_ptr, uint ch
return 1;
}
if (!zend_is_callable_check_class(Z_STRVAL_PP(obj), Z_STRLEN_PP(obj), fcc, error TSRMLS_CC)) {
if (!zend_is_callable_check_class(Z_STRVAL_PP(obj), Z_STRLEN_PP(obj), fcc, &strict_class, error TSRMLS_CC)) {
return 0;
}
@ -2757,7 +2795,7 @@ ZEND_API zend_bool zend_is_callable_ex(zval *callable, zval *object_ptr, uint ch
}
}
ret = zend_is_callable_check_func(check_flags, *method, fcc, error TSRMLS_CC);
ret = zend_is_callable_check_func(check_flags, *method, fcc, strict_class, error TSRMLS_CC);
if (fcc == &fcc_local &&
fcc->function_handler &&
((fcc->function_handler->type == ZEND_INTERNAL_FUNCTION &&

Loading…
Cancel
Save