cvs: php4 /ext/standard basic_functions.c
| From: | Jason Greene | Date: | Tue, 16 Jul 2002 14:14:23 +0000 |
| Subject: | cvs: php4 /ext/standard basic_functions.c | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-12851@lists.php.net to get a copy of this message | ||
jason Tue Jul 16 10:14:23 2002 EDT
Modified files:
/php4/ext/standard basic_functions.c
Log:
@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";
}
;
;
;
;
}
?>
Index: php4/ext/standard/basic_functions.c
diff -u php4/ext/standard/basic_functions.c:1.485 php4/ext/standard/basic_functions.c:1.486
--- php4/ext/standard/basic_functions.c:1.485 Wed Jul 10 11:23:47 2002
+++ php4/ext/standard/basic_functions.c Tue Jul 16 10:14:22 2002
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: basic_functions.c,v 1.485 2002/07/10 15:23:47 jason Exp $ */
+/* $Id: basic_functions.c,v 1.486 2002/07/16 14:14:22 jason Exp $ */
#include "php.h"
#include "php_streams.h"
@@ -95,6 +95,7 @@
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 @@
{
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 @@
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;