summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Zmievski <andrei@php.net>2000-02-11 21:14:42 +0000
committerAndrei Zmievski <andrei@php.net>2000-02-11 21:14:42 +0000
commita60e91b31351146caa1d0a15ff60c9029ea8654f (patch)
treef3f8026c12959e9fb6f945095d62d0739de5df40
parent94be61fde5f580b305537b54df17b0257ed1378f (diff)
downloadphp-git-a60e91b31351146caa1d0a15ff60c9029ea8654f.tar.gz
(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.
-rw-r--r--ext/standard/array.c10
-rw-r--r--ext/standard/basic_functions.c19
-rw-r--r--main/main.c9
-rw-r--r--main/php_globals.h1
4 files changed, 28 insertions, 11 deletions
diff --git a/ext/standard/array.c b/ext/standard/array.c
index 0d47ed68e8..82bb9efff8 100644
--- a/ext/standard/array.c
+++ b/ext/standard/array.c
@@ -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);
diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c
index 3e70b22f5d..f5c571a21a 100644
--- a/ext/standard/basic_functions.c
+++ b/ext/standard/basic_functions.c
@@ -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));
}
diff --git a/main/main.c b/main/main.c
index b1a0898b58..ab769466cd 100644
--- a/main/main.c
+++ b/main/main.c
@@ -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();
diff --git a/main/php_globals.h b/main/php_globals.h
index b6e086ced3..441ecec0d3 100644
--- a/main/php_globals.h
+++ b/main/php_globals.h
@@ -97,6 +97,7 @@ struct _php_core_globals {
long max_execution_time;
unsigned char header_is_being_sent;
+ zend_bool already_in_shutdown;
};