From: Dmitry Stogov Date: Tue, 4 May 2010 08:02:51 +0000 (+0000) Subject: Fixed a possible memory corruption in addcslashes(). X-Git-Tag: php-5.3.3RC1~205 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3a15e98155c2e3c7d5f07a4a22431711a8820993;p=php Fixed a possible memory corruption in addcslashes(). --- diff --git a/NEWS b/NEWS index 7186b06c3a..dc0b20bfd7 100644 --- a/NEWS +++ b/NEWS @@ -23,6 +23,8 @@ PHP NEWS - Fixed very rare memory leak in mysqlnd, when binding thousands of columns. (Andrey) +- Fixed a possible memory corruption in addcslashes(). Reporeted by Stefan + Esser (Dmitry) - Fixed a possible stack exaustion inside fnmatch(). Reporeted by Stefan Esser (Ilia) - Fixed a possible dechunking filter buffer overflow. Reported by Stefan Esser. diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 5433dc17e0..0b9823a989 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -251,22 +251,18 @@ ZEND_API int zend_get_object_classname(const zval *object, char **class_name, ze } /* }}} */ -static int parse_arg_object_to_string(zval **arg, char **p, int *pl, int type TSRMLS_DC) /* {{{ */ +static int parse_arg_object_to_string(zval **arg TSRMLS_DC) /* {{{ */ { if (Z_OBJ_HANDLER_PP(arg, cast_object)) { SEPARATE_ZVAL_IF_NOT_REF(arg); - if (Z_OBJ_HANDLER_PP(arg, cast_object)(*arg, *arg, type TSRMLS_CC) == SUCCESS) { - *pl = Z_STRLEN_PP(arg); - *p = Z_STRVAL_PP(arg); + if (Z_OBJ_HANDLER_PP(arg, cast_object)(*arg, *arg, IS_STRING TSRMLS_CC) == SUCCESS) { return SUCCESS; } } /* Standard PHP objects */ if (Z_OBJ_HT_PP(arg) == &std_object_handlers || !Z_OBJ_HANDLER_PP(arg, cast_object)) { SEPARATE_ZVAL_IF_NOT_REF(arg); - if (zend_std_cast_object_tostring(*arg, *arg, type TSRMLS_CC) == SUCCESS) { - *pl = Z_STRLEN_PP(arg); - *p = Z_STRVAL_PP(arg); + if (zend_std_cast_object_tostring(*arg, *arg, IS_STRING TSRMLS_CC) == SUCCESS) { return SUCCESS; } } @@ -281,8 +277,6 @@ static int parse_arg_object_to_string(zval **arg, char **p, int *pl, int type TS if (!use_copy) { ZVAL_ZVAL(*arg, z, 1, 1); } - *pl = Z_STRLEN_PP(arg); - *p = Z_STRVAL_PP(arg); return SUCCESS; } zval_ptr_dtor(&z); @@ -423,10 +417,6 @@ static char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, char **sp break; case IS_OBJECT: - if (parse_arg_object_to_string(arg, p, pl, IS_STRING TSRMLS_CC) == SUCCESS) { - break; - } - case IS_ARRAY: case IS_RESOURCE: default: @@ -680,7 +670,7 @@ static int zend_parse_va_args(int num_args, char *type_spec, va_list *va, int fl int max_num_args = 0; int post_varargs = 0; zval **arg; - int arg_count; + int arg_count = (int)(zend_uintptr_t) *(zend_vm_stack_top(TSRMLS_C) - 1); int quiet = flags & ZEND_PARSE_PARAMS_QUIET; zend_bool have_varargs = 0; zval ****varargs = NULL; @@ -689,14 +679,21 @@ static int zend_parse_va_args(int num_args, char *type_spec, va_list *va, int fl for (spec_walk = type_spec; *spec_walk; spec_walk++) { c = *spec_walk; switch (c) { + case 's': + if (max_num_args < arg_count) { + arg = (zval **) (zend_vm_stack_top(TSRMLS_C) - 1 - (arg_count - max_num_args)); + if (Z_TYPE_PP(arg) == IS_OBJECT) { + parse_arg_object_to_string(arg TSRMLS_CC); + } + } + /* break missing intentionally */ case 'l': case 'd': - case 's': case 'b': + case 'H': case 'b': case 'r': case 'a': case 'o': case 'O': case 'z': case 'Z': case 'C': case 'h': case 'f': case 'A': - case 'H': max_num_args++; break; @@ -770,8 +767,6 @@ static int zend_parse_va_args(int num_args, char *type_spec, va_list *va, int fl return FAILURE; } - arg_count = (int)(zend_uintptr_t) *(zend_vm_stack_top(TSRMLS_C) - 1); - if (num_args > arg_count) { zend_error(E_WARNING, "%s(): could not obtain parameters for parsing", get_active_function_name(TSRMLS_C));