mirror of
https://github.com/php/php-src.git
synced 2024-09-22 02:17:32 +00:00
(request_shutdown) Prevent infinite loop on shutdown if there is an error
in shutdown function. (php_array_walk) Print a warning if the walk function doesn't exist. Split shutdown function call into a separate function that's called with zend_hash_apply() instead of as destructor to keep hash consistent. This fixes bug #3419.
This commit is contained in:
parent
94be61fde5
commit
a60e91b313
@ -825,12 +825,14 @@ static int php_array_walk(HashTable *target_hash, zval **userdata)
|
||||
}
|
||||
|
||||
/* Call the userland function */
|
||||
call_user_function_ex(CG(function_table), NULL, *BG(array_walk_func_name),
|
||||
&retval_ptr, userdata ? 3 : 2, args, 0);
|
||||
if (call_user_function_ex(CG(function_table), NULL, *BG(array_walk_func_name),
|
||||
&retval_ptr, userdata ? 3 : 2, args, 0) == SUCCESS) {
|
||||
|
||||
if (retval_ptr) {
|
||||
zval_ptr_dtor(&retval_ptr);
|
||||
}
|
||||
} else
|
||||
php_error(E_WARNING,"Unable to call %s() - function does not exist",
|
||||
(*BG(array_walk_func_name))->value.str.val);
|
||||
|
||||
/* Clean up the key */
|
||||
if (zend_hash_get_current_key_type(target_hash) == HASH_KEY_IS_STRING)
|
||||
efree(key->value.str.val);
|
||||
|
@ -1045,25 +1045,34 @@ PHP_FUNCTION(call_user_method)
|
||||
|
||||
void user_shutdown_function_dtor(php_shutdown_function_entry *shutdown_function_entry)
|
||||
{
|
||||
pval retval;
|
||||
int i;
|
||||
CLS_FETCH();
|
||||
|
||||
if (call_user_function(CG(function_table), NULL, shutdown_function_entry->arguments[0], &retval, shutdown_function_entry->arg_count-1, shutdown_function_entry->arguments+1)==SUCCESS) {
|
||||
pval_destructor(&retval);
|
||||
}
|
||||
for (i=0; i<shutdown_function_entry->arg_count; i++) {
|
||||
zval_ptr_dtor(&shutdown_function_entry->arguments[i]);
|
||||
}
|
||||
efree(shutdown_function_entry->arguments);
|
||||
}
|
||||
|
||||
int user_shutdown_function_call(php_shutdown_function_entry *shutdown_function_entry)
|
||||
{
|
||||
zval retval;
|
||||
CLS_FETCH();
|
||||
|
||||
if (call_user_function(CG(function_table), NULL, shutdown_function_entry->arguments[0], &retval, shutdown_function_entry->arg_count-1, shutdown_function_entry->arguments+1)==SUCCESS) {
|
||||
zval_dtor(&retval);
|
||||
} else
|
||||
php_error(E_WARNING,"Unable to call %s() - function does not exist",
|
||||
shutdown_function_entry->arguments[0]->value.str.val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void php_call_shutdown_functions(void)
|
||||
{
|
||||
BLS_FETCH();
|
||||
|
||||
if (BG(user_shutdown_function_names)) {
|
||||
zend_hash_apply(BG(user_shutdown_function_names),
|
||||
(apply_func_t)user_shutdown_function_call);
|
||||
zend_hash_destroy(BG(user_shutdown_function_names));
|
||||
efree(BG(user_shutdown_function_names));
|
||||
}
|
||||
|
@ -624,7 +624,8 @@ int php_request_startup(CLS_D ELS_DC PLS_DC SLS_DC)
|
||||
php_output_startup();
|
||||
|
||||
/* initialize global variables */
|
||||
PG(header_is_being_sent)=0;
|
||||
PG(header_is_being_sent) = 0;
|
||||
PG(already_in_shutdown) = 0;
|
||||
|
||||
zend_activate(CLS_C ELS_CC);
|
||||
sapi_activate(SLS_C);
|
||||
@ -658,11 +659,15 @@ void php_request_shutdown(void *dummy)
|
||||
CLS_FETCH();
|
||||
ELS_FETCH();
|
||||
SLS_FETCH();
|
||||
PLS_FETCH();
|
||||
|
||||
sapi_send_headers();
|
||||
php_end_ob_buffering(SG(request_info).headers_only?0:1);
|
||||
|
||||
php_call_shutdown_functions();
|
||||
if (!PG(already_in_shutdown)) {
|
||||
PG(already_in_shutdown) = 1;
|
||||
php_call_shutdown_functions();
|
||||
}
|
||||
|
||||
php_ini_rshutdown();
|
||||
|
||||
|
@ -97,6 +97,7 @@ struct _php_core_globals {
|
||||
long max_execution_time;
|
||||
|
||||
unsigned char header_is_being_sent;
|
||||
zend_bool already_in_shutdown;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user