(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:
Andrei Zmievski 2000-02-11 21:14:42 +00:00
parent 94be61fde5
commit a60e91b313
4 changed files with 28 additions and 11 deletions

View File

@ -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);

View File

@ -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));
}

View File

@ -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();

View File

@ -97,6 +97,7 @@ struct _php_core_globals {
long max_execution_time;
unsigned char header_is_being_sent;
zend_bool already_in_shutdown;
};