mirror of
https://github.com/php/php-src.git
synced 2024-12-27 19:00:27 +08:00
@Fixed infinite recursion crash bug in ticks (Jason)
Prevent reenterant calls to a user tick function by flagging the function entry during call. This prevents code like the following from infinitely recursing until a crash occurs: <?php register_tick_function(a); declare(ticks=1) { function a() { print "blah\n"; } ; ; ; ; } ?>
This commit is contained in:
parent
950a576f73
commit
9b68acb7f7
@ -95,6 +95,7 @@ typedef struct _php_shutdown_function_entry {
|
||||
typedef struct _user_tick_function_entry {
|
||||
zval **arguments;
|
||||
int arg_count;
|
||||
int calling;
|
||||
} user_tick_function_entry;
|
||||
|
||||
/* some prototypes for local functions */
|
||||
@ -1754,29 +1755,36 @@ static void user_tick_function_call(user_tick_function_entry *tick_fe TSRMLS_DC)
|
||||
{
|
||||
zval retval;
|
||||
zval *function = tick_fe->arguments[0];
|
||||
|
||||
/* Prevent reentrant calls to the same user ticks function */
|
||||
if (! tick_fe->calling) {
|
||||
tick_fe->calling = 1;
|
||||
|
||||
if (call_user_function( EG(function_table), NULL,
|
||||
function,
|
||||
&retval,
|
||||
tick_fe->arg_count - 1,
|
||||
tick_fe->arguments+1
|
||||
TSRMLS_CC) == SUCCESS) {
|
||||
zval_dtor(&retval);
|
||||
if (call_user_function( EG(function_table), NULL,
|
||||
function,
|
||||
&retval,
|
||||
tick_fe->arg_count - 1,
|
||||
tick_fe->arguments+1
|
||||
TSRMLS_CC) == SUCCESS) {
|
||||
zval_dtor(&retval);
|
||||
|
||||
} else {
|
||||
zval **obj, **method;
|
||||
|
||||
if (Z_TYPE_P(function) == IS_STRING) {
|
||||
php_error(E_WARNING, "%s(): Unable to call %s() - function does not exist", get_active_function_name(TSRMLS_C), Z_STRVAL_P(function));
|
||||
} else if ( Z_TYPE_P(function) == IS_ARRAY
|
||||
&& zend_hash_index_find(Z_ARRVAL_P(function), 0, (void **) &obj) == SUCCESS
|
||||
&& zend_hash_index_find(Z_ARRVAL_P(function), 1, (void **) &method) == SUCCESS
|
||||
&& Z_TYPE_PP(obj) == IS_OBJECT
|
||||
&& Z_TYPE_PP(method) == IS_STRING ) {
|
||||
php_error(E_WARNING, "%s(): Unable to call %s::%s() - function does not exist", get_active_function_name(TSRMLS_C), Z_OBJCE_PP(obj)->name, Z_STRVAL_PP(method));
|
||||
} else {
|
||||
php_error(E_WARNING, "%s(): Unable to call tick function", get_active_function_name(TSRMLS_C));
|
||||
zval **obj, **method;
|
||||
|
||||
if (Z_TYPE_P(function) == IS_STRING) {
|
||||
php_error(E_WARNING, "%s(): Unable to call %s() - function does not exist", get_active_function_name(TSRMLS_C), Z_STRVAL_P(function));
|
||||
} else if ( Z_TYPE_P(function) == IS_ARRAY
|
||||
&& zend_hash_index_find(Z_ARRVAL_P(function), 0, (void **) &obj) == SUCCESS
|
||||
&& zend_hash_index_find(Z_ARRVAL_P(function), 1, (void **) &method) == SUCCESS
|
||||
&& Z_TYPE_PP(obj) == IS_OBJECT
|
||||
&& Z_TYPE_PP(method) == IS_STRING ) {
|
||||
php_error(E_WARNING, "%s(): Unable to call %s::%s() - function does not exist", get_active_function_name(TSRMLS_C), Z_OBJCE_PP(obj)->name, Z_STRVAL_PP(method));
|
||||
} else {
|
||||
php_error(E_WARNING, "%s(): Unable to call tick function", get_active_function_name(TSRMLS_C));
|
||||
}
|
||||
}
|
||||
|
||||
tick_fe->calling = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2242,6 +2250,7 @@ PHP_FUNCTION(register_tick_function)
|
||||
user_tick_function_entry tick_fe;
|
||||
int i;
|
||||
|
||||
tick_fe.calling = 0;
|
||||
tick_fe.arg_count = ZEND_NUM_ARGS();
|
||||
if (tick_fe.arg_count < 1) {
|
||||
WRONG_PARAM_COUNT;
|
||||
|
Loading…
Reference in New Issue
Block a user