]> granicus.if.org Git - php/commitdiff
Fixed a possible memory corruption in addcslashes().
authorDmitry Stogov <dmitry@php.net>
Tue, 4 May 2010 08:02:51 +0000 (08:02 +0000)
committerDmitry Stogov <dmitry@php.net>
Tue, 4 May 2010 08:02:51 +0000 (08:02 +0000)
NEWS
Zend/zend_API.c

diff --git a/NEWS b/NEWS
index 7186b06c3a54d46ad90aaf65568471b32ec6e251..dc0b20bfd73612b1eefb835bc9f42c8ab08efb48 100644 (file)
--- 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.
index 5433dc17e094dab9ccc547f4bc140345c91b0ac8..0b9823a989ba553676bb1beda3a94f2e43382c66 100644 (file)
@@ -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));