From be895bcb96157b5a36d1183d3b9567ede57a45f8 Mon Sep 17 00:00:00 2001 From: Zeev Suraski Date: Wed, 13 Dec 2000 22:50:10 +0000 Subject: [PATCH] Fix call_user_function() with objects - it could leak under certain circumstances --- Zend/zend_API.h | 4 ++-- Zend/zend_execute_API.c | 27 +++++++++++++-------------- ext/standard/basic_functions.c | 4 ++-- ext/standard/exec.c | 3 ++- ext/standard/var.c | 4 ++-- ext/wddx/wddx.c | 4 ++-- ext/xml/xml.c | 2 +- 7 files changed, 24 insertions(+), 24 deletions(-) diff --git a/Zend/zend_API.h b/Zend/zend_API.h index 8125193fcd..824bfa0136 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -177,8 +177,8 @@ ZEND_API int add_get_assoc_stringl(zval *arg, char *key, char *str, uint length, ZEND_API int add_get_index_string(zval *arg, uint idx, char *str, void **dest, int duplicate); ZEND_API int add_get_index_stringl(zval *arg, uint idx, char *str, uint length, void **dest, int duplicate); -ZEND_API int call_user_function(HashTable *function_table, zval *object, zval *function_name, zval *retval_ptr, int param_count, zval *params[]); -ZEND_API int call_user_function_ex(HashTable *function_table, zval *object, zval *function_name, zval **retval_ptr_ptr, int param_count, zval **params[], int no_separation, HashTable *symbol_table); +ZEND_API int call_user_function(HashTable *function_table, zval **object_pp, zval *function_name, zval *retval_ptr, int param_count, zval *params[]); +ZEND_API int call_user_function_ex(HashTable *function_table, zval **object_pp, zval *function_name, zval **retval_ptr_ptr, int param_count, zval **params[], int no_separation, HashTable *symbol_table); ZEND_API int add_property_long(zval *arg, char *key, long l); ZEND_API int add_property_unset(zval *arg, char *key); diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 9834499195..8fe3ce1fb6 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -312,7 +312,7 @@ ZEND_API int zval_update_constant(zval **pp, void *arg) } -int call_user_function(HashTable *function_table, zval *object, zval *function_name, zval *retval_ptr, int param_count, zval *params[]) +int call_user_function(HashTable *function_table, zval **object_pp, zval *function_name, zval *retval_ptr, int param_count, zval *params[]) { zval ***params_array = (zval ***) emalloc(sizeof(zval **)*param_count); int i; @@ -322,7 +322,7 @@ int call_user_function(HashTable *function_table, zval *object, zval *function_n for (i=0; iis_ref = 1; + object_pp = tmp_object_ptr; + (*object_pp)->is_ref = 1; } - if (object) { - if (object->type != IS_OBJECT) { + if (object_pp) { + if (Z_TYPE_PP(object_pp) != IS_OBJECT) { return FAILURE; } - function_table = &object->value.obj.ce->function_table; + function_table = &(*object_pp)->value.obj.ce->function_table; } if (function_name->type!=IS_STRING) { @@ -422,14 +422,13 @@ int call_user_function_ex(HashTable *function_table, zval *object, zval *functio ALLOC_HASHTABLE(EG(active_symbol_table)); zend_hash_init(EG(active_symbol_table), 0, NULL, ZVAL_PTR_DTOR, 0); } - if (object) { + if (object_pp) { zval *dummy, **this_ptr; - + ALLOC_ZVAL(dummy); - INIT_ZVAL(*dummy); - + INIT_ZVAL(*dummy); zend_hash_update(EG(active_symbol_table), "this", sizeof("this"), &dummy, sizeof(zval *), (void **) &this_ptr); - zend_assign_to_variable_reference(NULL, this_ptr, &object, NULL ELS_CC); + zend_assign_to_variable_reference(NULL, this_ptr, object_pp, NULL ELS_CC); } original_return_value = EG(return_value_ptr_ptr); original_op_array = EG(active_op_array); @@ -447,7 +446,7 @@ int call_user_function_ex(HashTable *function_table, zval *object, zval *functio EG(opline_ptr) = original_opline_ptr; } else { ALLOC_INIT_ZVAL(*retval_ptr_ptr); - ((zend_internal_function *) function_state.function)->handler(param_count, *retval_ptr_ptr, object, 1 ELS_CC); + ((zend_internal_function *) function_state.function)->handler(param_count, *retval_ptr_ptr, *object_pp, 1 ELS_CC); INIT_PZVAL(*retval_ptr_ptr); } zend_ptr_stack_clear_multiple(ELS_C); diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index ada3bd0d5e..5bcea01d01 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -1618,7 +1618,7 @@ PHP_FUNCTION(call_user_method) SEPARATE_ZVAL(params[0]); SEPARATE_ZVAL(params[1]); convert_to_string(*params[0]); - if (call_user_function_ex(CG(function_table), *params[1], *params[0], &retval_ptr, arg_count-2, params+2, 1, NULL)==SUCCESS + if (call_user_function_ex(CG(function_table), *params[1], params[0], &retval_ptr, arg_count-2, params+2, 1, NULL)==SUCCESS && retval_ptr) { COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr); } else { @@ -1659,7 +1659,7 @@ PHP_FUNCTION(call_user_method_array) zend_hash_move_forward(params_ar)) element++; - if (call_user_function_ex(CG(function_table), *obj, *method_name, &retval_ptr, num_elems, method_args, 1, NULL) == SUCCESS + if (call_user_function_ex(CG(function_table), obj, *method_name, &retval_ptr, num_elems, method_args, 1, NULL) == SUCCESS && retval_ptr) { COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr); } else { diff --git a/ext/standard/exec.c b/ext/standard/exec.c index 1adaa2b2e6..cfa1abf033 100644 --- a/ext/standard/exec.c +++ b/ext/standard/exec.c @@ -421,7 +421,8 @@ PHP_FUNCTION(shell_exec) allocated_space = EXEC_INPUT_BUF; ret = (char *) emalloc(allocated_space); while (1) { - readbytes = fread(ret+total_readbytes,1,EXEC_INPUT_BUF,in); +// readbytes = fread(ret+total_readbytes,1,EXEC_INPUT_BUF,in); + readbytes = fread(ret+total_readbytes,1,5,in); if (readbytes<=0) { break; } diff --git a/ext/standard/var.c b/ext/standard/var.c index 84c04ed333..0eb531eefb 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -240,7 +240,7 @@ void php_var_serialize(pval *buf, pval **struc, HashTable *var_hash) MAKE_STD_ZVAL(fname); ZVAL_STRING(fname,"__sleep",1); - res = call_user_function_ex(CG(function_table), *struc, fname, &retval_ptr, 0, 0, 1, NULL); + res = call_user_function_ex(CG(function_table), struc, fname, &retval_ptr, 0, 0, 1, NULL); if (res == SUCCESS) { if (retval_ptr && HASH_OF(retval_ptr)) { @@ -597,7 +597,7 @@ int php_var_unserialize(pval **rval, const char **p, const char *max, HashTable MAKE_STD_ZVAL(fname); ZVAL_STRING(fname,"__wakeup",1); - call_user_function_ex(CG(function_table), *rval, fname, &retval_ptr, 0, 0, 1, NULL); + call_user_function_ex(CG(function_table), rval, fname, &retval_ptr, 0, 0, 1, NULL); zval_dtor(fname); FREE_ZVAL(fname); diff --git a/ext/wddx/wddx.c b/ext/wddx/wddx.c index f74e7c472c..ed838504a6 100644 --- a/ext/wddx/wddx.c +++ b/ext/wddx/wddx.c @@ -424,7 +424,7 @@ static void php_wddx_serialize_object(wddx_packet *packet, zval *obj) * We try to call __sleep() method on object. It's supposed to return an * array of property names to be serialized. */ - if (call_user_function_ex(CG(function_table), obj, fname, &retval, 0, 0, 1, NULL) == SUCCESS) { + if (call_user_function_ex(CG(function_table), &obj, fname, &retval, 0, 0, 1, NULL) == SUCCESS) { if (retval && HASH_OF(retval)) { PHP_CLASS_ATTRIBUTES; @@ -781,7 +781,7 @@ static void php_wddx_pop_element(void *user_data, const char *name) MAKE_STD_ZVAL(fname); ZVAL_STRING(fname, "__wakeup", 1); - call_user_function_ex(NULL, ent1->data, fname, &retval, 0, 0, 0, NULL); + call_user_function_ex(NULL, &ent1->data, fname, &retval, 0, 0, 0, NULL); zval_dtor(fname); FREE_ZVAL(fname); diff --git a/ext/xml/xml.c b/ext/xml/xml.c index b7f56199fa..afcf223644 100644 --- a/ext/xml/xml.c +++ b/ext/xml/xml.c @@ -358,7 +358,7 @@ xml_call_handler(xml_parser *parser, zval *handler, int argc, zval **argv) retval->type = IS_BOOL; retval->value.lval = 0; - result = call_user_function(EG(function_table), parser->object, handler, retval, argc, argv); + result = call_user_function(EG(function_table), &parser->object, handler, retval, argc, argv); if (result == FAILURE) { zval **method; -- 2.40.0