mirror of
https://github.com/php/php-src.git
synced 2025-08-18 23:18:56 +02:00
- Fixed bug #32647 (Using register_shutdown_function() with invalid callback can crash PHP)
This commit is contained in:
parent
62a1f82e4a
commit
4c3fdcaa4e
1 changed files with 32 additions and 22 deletions
|
@ -2251,17 +2251,21 @@ void user_tick_function_dtor(user_tick_function_entry *tick_function_entry)
|
||||||
static int user_shutdown_function_call(php_shutdown_function_entry *shutdown_function_entry TSRMLS_DC)
|
static int user_shutdown_function_call(php_shutdown_function_entry *shutdown_function_entry TSRMLS_DC)
|
||||||
{
|
{
|
||||||
zval retval;
|
zval retval;
|
||||||
|
char *function_name = NULL;
|
||||||
|
|
||||||
if (call_user_function( EG(function_table), NULL,
|
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],
|
shutdown_function_entry->arguments[0],
|
||||||
&retval,
|
&retval,
|
||||||
shutdown_function_entry->arg_count - 1,
|
shutdown_function_entry->arg_count - 1,
|
||||||
shutdown_function_entry->arguments + 1
|
shutdown_function_entry->arguments + 1
|
||||||
TSRMLS_CC ) == SUCCESS ) {
|
TSRMLS_CC ) == SUCCESS)
|
||||||
|
{
|
||||||
zval_dtor(&retval);
|
zval_dtor(&retval);
|
||||||
|
}
|
||||||
} else {
|
if (function_name) {
|
||||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call %s() - function does not exist", Z_STRVAL_P(shutdown_function_entry->arguments[0]));
|
efree(function_name);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2354,6 +2358,7 @@ void php_free_shutdown_functions(TSRMLS_D)
|
||||||
PHP_FUNCTION(register_shutdown_function)
|
PHP_FUNCTION(register_shutdown_function)
|
||||||
{
|
{
|
||||||
php_shutdown_function_entry shutdown_function_entry;
|
php_shutdown_function_entry shutdown_function_entry;
|
||||||
|
char *function_name = NULL;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
shutdown_function_entry.arg_count = ZEND_NUM_ARGS();
|
shutdown_function_entry.arg_count = ZEND_NUM_ARGS();
|
||||||
|
@ -2362,17 +2367,18 @@ PHP_FUNCTION(register_shutdown_function)
|
||||||
WRONG_PARAM_COUNT;
|
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) {
|
if (zend_get_parameters_array(ht, shutdown_function_entry.arg_count, shutdown_function_entry.arguments) == FAILURE) {
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Prevent entering of anything but arrays/strings */
|
/* Prevent entering of anything but valid callback (syntax check only!) */
|
||||||
if (Z_TYPE_P(shutdown_function_entry.arguments[0]) != IS_ARRAY) {
|
if (!zend_is_callable(shutdown_function_entry.arguments[0], 1, &function_name)) {
|
||||||
convert_to_string(shutdown_function_entry.arguments[0]);
|
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)) {
|
if (!BG(user_shutdown_function_names)) {
|
||||||
ALLOC_HASHTABLE(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);
|
zend_hash_init(BG(user_shutdown_function_names), 0, NULL, (void (*)(void *)) user_shutdown_function_dtor, 0);
|
||||||
|
@ -2382,6 +2388,10 @@ PHP_FUNCTION(register_shutdown_function)
|
||||||
shutdown_function_entry.arguments[i]->refcount++;
|
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);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue