sniper Thu Apr 21 10:44:30 2005 EDT
Modified files:
/php-src/ext/standard basic_functions.c
Log:
- Fixed bug #32647 (Using register_shutdown_function() with invalid callback
can crash PHP)
http://cvs.php.net/diff.php/php-src/ext/standard/basic_functions.c?r1=1.709&r2=1.710&ty=u
Index: php-src/ext/standard/basic_functions.c
diff -u php-src/ext/standard/basic_functions.c:1.709
php-src/ext/standard/basic_functions.c:1.710
--- php-src/ext/standard/basic_functions.c:1.709 Sun Apr 10 12:25:11 2005
+++ php-src/ext/standard/basic_functions.c Thu Apr 21 10:44:29 2005
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: basic_functions.c,v 1.709 2005/04/10 16:25:11 iliaa Exp $ */
+/* $Id: basic_functions.c,v 1.710 2005/04/21 14:44:29 sniper Exp $ */
#include "php.h"
#include "php_streams.h"
@@ -2251,17 +2251,21 @@
static int user_shutdown_function_call(php_shutdown_function_entry
*shutdown_function_entry TSRMLS_DC)
{
zval retval;
+ char *function_name = NULL;
- if (call_user_function( EG(function_table), NULL,
-
shutdown_function_entry->arguments[0],
- &retval,
-
shutdown_function_entry->arg_count - 1,
-
shutdown_function_entry->arguments + 1
- TSRMLS_CC ) == SUCCESS
) {
+ if (!zend_is_callable(shutdown_function_entry->arguments[0], 0,
&function_name)) {
+ php_error(E_WARNING, "(Registered shutdown functions) Unable to
call %s() - function does not exist", function_name);
+ } else if (call_user_function(EG(function_table), NULL,
+
shutdown_function_entry->arguments[0],
+ &retval,
+
shutdown_function_entry->arg_count - 1,
+
shutdown_function_entry->arguments + 1
+ TSRMLS_CC ) ==
SUCCESS)
+ {
zval_dtor(&retval);
-
- } else {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call
%s() - function does not exist",
Z_STRVAL_P(shutdown_function_entry->arguments[0]));
+ }
+ if (function_name) {
+ efree(function_name);
}
return 0;
}
@@ -2354,6 +2358,7 @@
PHP_FUNCTION(register_shutdown_function)
{
php_shutdown_function_entry shutdown_function_entry;
+ char *function_name = NULL;
int i;
shutdown_function_entry.arg_count = ZEND_NUM_ARGS();
@@ -2362,26 +2367,31 @@
WRONG_PARAM_COUNT;
}
- shutdown_function_entry.arguments = (pval **) safe_emalloc(sizeof(pval
*), shutdown_function_entry.arg_count, 0);
+ shutdown_function_entry.arguments = (zval **) safe_emalloc(sizeof(zval
*), shutdown_function_entry.arg_count, 0);
if (zend_get_parameters_array(ht, shutdown_function_entry.arg_count,
shutdown_function_entry.arguments) == FAILURE) {
RETURN_FALSE;
}
- /* Prevent entering of anything but arrays/strings */
- if (Z_TYPE_P(shutdown_function_entry.arguments[0]) != IS_ARRAY) {
- convert_to_string(shutdown_function_entry.arguments[0]);
- }
-
- if (!BG(user_shutdown_function_names)) {
- ALLOC_HASHTABLE(BG(user_shutdown_function_names));
- zend_hash_init(BG(user_shutdown_function_names), 0, NULL, (void
(*)(void *)) user_shutdown_function_dtor, 0);
- }
+ /* Prevent entering of anything but valid callback (syntax check only!)
*/
+ if (!zend_is_callable(shutdown_function_entry.arguments[0], 1,
&function_name)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid shutdown
callback '%s' passed", function_name);
+ efree(shutdown_function_entry.arguments);
+ RETVAL_FALSE;
+ } else {
+ if (!BG(user_shutdown_function_names)) {
+ ALLOC_HASHTABLE(BG(user_shutdown_function_names));
+ zend_hash_init(BG(user_shutdown_function_names), 0,
NULL, (void (*)(void *)) user_shutdown_function_dtor, 0);
+ }
- for (i = 0; i < shutdown_function_entry.arg_count; i++) {
- shutdown_function_entry.arguments[i]->refcount++;
+ for (i = 0; i < shutdown_function_entry.arg_count; i++) {
+ shutdown_function_entry.arguments[i]->refcount++;
+ }
+ zend_hash_next_index_insert(BG(user_shutdown_function_names),
&shutdown_function_entry, sizeof(php_shutdown_function_entry), NULL);
+ }
+ if (function_name) {
+ efree(function_name);
}
- zend_hash_next_index_insert(BG(user_shutdown_function_names),
&shutdown_function_entry, sizeof(php_shutdown_function_entry), NULL);
}
/* }}} */
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php