]> granicus.if.org Git - php/commitdiff
Fixed several memory leaks
authorXinchen Hui <laruence@gmail.com>
Mon, 24 Feb 2014 07:03:35 +0000 (15:03 +0800)
committerXinchen Hui <laruence@gmail.com>
Mon, 24 Feb 2014 07:03:35 +0000 (15:03 +0800)
Zend/zend_API.c
ext/standard/cyr_convert.c
ext/standard/string.c

index b54996bcae35897af5c1eef18ebba35aa3c2c9c7..23a9139c8e26d666758980c021d263a62ca52d54 100644 (file)
@@ -300,6 +300,45 @@ static int parse_arg_object_to_string(zval *arg, char **p, int *pl, int type TSR
 }
 /* }}} */
 
+static int parse_arg_object_to_str(zval *arg, zend_string **str, int type TSRMLS_DC) /* {{{ */
+{
+       if (Z_OBJ_HANDLER_P(arg, cast_object)) {
+               zval obj;
+               if (Z_OBJ_HANDLER_P(arg, cast_object)(arg, &obj, type TSRMLS_CC) == SUCCESS) {
+                       zval_ptr_dtor(arg);
+                       ZVAL_COPY_VALUE(arg, &obj);
+                       *str = Z_STR_P(arg);
+                       return SUCCESS;
+               }
+       }
+       /* Standard PHP objects */
+       if (Z_OBJ_HT_P(arg) == &std_object_handlers || !Z_OBJ_HANDLER_P(arg, cast_object)) {
+               SEPARATE_ZVAL_IF_NOT_REF(arg);
+               if (zend_std_cast_object_tostring(arg, arg, type TSRMLS_CC) == SUCCESS) {
+                       *str = Z_STR_P(arg);
+                       return SUCCESS;
+               }
+       }
+       if (!Z_OBJ_HANDLER_P(arg, cast_object) && Z_OBJ_HANDLER_P(arg, get)) {
+               int use_copy;
+               zval *z = Z_OBJ_HANDLER_P(arg, get)(arg TSRMLS_CC);
+               Z_ADDREF_P(z);
+               if(Z_TYPE_P(z) != IS_OBJECT) {
+                       zval_dtor(arg);
+                       Z_TYPE_P(arg) = IS_NULL;
+                       zend_make_printable_zval(z, arg, &use_copy);
+                       if (!use_copy) {
+                               ZVAL_ZVAL(arg, z, 1, 1);
+                       }
+                       *str = Z_STR_P(arg);
+                       return SUCCESS;
+               }
+               zval_ptr_dtor(z);
+       }
+       return FAILURE;
+}
+/* }}} */
+
 static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, const char **spec, char **error, int *severity TSRMLS_DC) /* {{{ */
 {
        const char *spec_walk = *spec;
@@ -498,11 +537,7 @@ static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, cons
                                                break;
 
                                        case IS_OBJECT: {
-                                               char *p;
-                                               int pl;
-
-                                               if (parse_arg_object_to_string(arg, &p, &pl, IS_STRING TSRMLS_CC) == SUCCESS) {
-                                                       *str = STR_INIT(p, pl, 0);
+                                               if (parse_arg_object_to_str(arg, str, IS_STRING TSRMLS_CC) == SUCCESS) {
                                                        break;
                                                }
                                        }
index bc482367afa6c25348c4609913d5cd1ea72db300..280aba5cecaa383348074149a4b4364e222f0212 100644 (file)
@@ -273,17 +273,16 @@ PHP_FUNCTION(convert_cyr_string)
 {
        char *input, *fr_cs, *to_cs;
        int input_len, fr_cs_len, to_cs_len;
-       unsigned char *str;
+       zend_string *str;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss", &input, &input_len, &fr_cs, &fr_cs_len, &to_cs, &to_cs_len) == FAILURE) {
                return;
        }
 
-       str = (unsigned char*) estrndup(input, input_len);
+       str = STR_INIT(input, input_len, 0);
 
-       php_convert_cyr_string(str, input_len, fr_cs[0], to_cs[0] TSRMLS_CC);
-//???  RETVAL_STRING((char *)str, 0);
-       RETVAL_STRING((char *)str);
+       php_convert_cyr_string(str->val, str->len, fr_cs[0], to_cs[0] TSRMLS_CC);
+       RETVAL_STR(str);
 }
 /* }}} */
 
index 90391ab14edc131948b200310f99c7abef46ce57..3eab9a062330010ee2d47e1604efdf6dacb0b0aa 100644 (file)
@@ -1080,39 +1080,36 @@ PHPAPI void php_explode_negative_limit(zval *delim, zval *str, zval *return_valu
    Splits a string on string separator and return array of components. If limit is positive only limit number of components is returned. If limit is negative all components except the last abs(limit) are returned. */
 PHP_FUNCTION(explode)
 {
-       char *str, *delim;
-       int str_len = 0, delim_len = 0;
+       zend_string *str, *delim;
        long limit = LONG_MAX; /* No limit */
        zval zdelim, zstr;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &delim, &delim_len, &str, &str_len, &limit) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "SS|l", &delim, &str, &limit) == FAILURE) {
                return;
        }
 
-       if (delim_len == 0) {
+       if (delim->len == 0) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty delimiter");
                RETURN_FALSE;
        }
 
        array_init(return_value);
 
-       if (str_len == 0) {
+       if (str->len == 0) {
                if (limit >= 0) {
                        add_next_index_stringl(return_value, "", sizeof("") - 1, 1);
                }
                return;
        }
 
-//???  ZVAL_STRINGL(&zstr, str, str_len, 0);
-//???  ZVAL_STRINGL(&zdelim, delim, delim_len, 0);
-       ZVAL_STRINGL(&zstr, str, str_len);
-       ZVAL_STRINGL(&zdelim, delim, delim_len);
+       ZVAL_STR(&zstr, str);
+       ZVAL_STR(&zdelim, delim);
        if (limit > 1) {
                php_explode(&zdelim, &zstr, return_value, limit);
        } else if (limit < 0) {
                php_explode_negative_limit(&zdelim, &zstr, return_value, limit);
        } else {
-               add_index_stringl(return_value, 0, str, str_len, 1);
+               add_index_stringl(return_value, 0, str->val, str->len, 1);
        }
 }
 /* }}} */
@@ -4363,7 +4360,10 @@ PHP_FUNCTION(setlocale)
                if (retval) {
                        /* Remember if locale was changed */
                        if (loc) {
-//???                          STR_FREE(BG(locale_string));
+//???                  STR_FREE(BG(locale_string));
+                               if (BG(locale_string)) {
+                                       efree(BG(locale_string));
+                               }
                                BG(locale_string) = estrdup(retval);
                        }