]> granicus.if.org Git - php/commitdiff
Improved trim/ltrim/rtrim functions.
authorDmitry Stogov <dmitry@zend.com>
Tue, 23 Dec 2014 01:29:41 +0000 (04:29 +0300)
committerDmitry Stogov <dmitry@zend.com>
Tue, 23 Dec 2014 01:29:41 +0000 (04:29 +0300)
Now php_trim() operates on zend_string and returns zend_string (it may return the same zend_string).

ext/mbstring/mbstring.c
ext/simplexml/simplexml.c
ext/standard/http_fopen_wrapper.c
ext/standard/mail.c
ext/standard/php_string.h
ext/standard/string.c

index 1e7cb5bd73ac02591dbf894fa621239054bb490c..d816ee52e75c2e91a727fba6e9fdfab420681bc3 100644 (file)
@@ -1437,17 +1437,17 @@ static PHP_INI_MH(OnUpdate_mbstring_encoding_translation)
 /* {{{ static PHP_INI_MH(OnUpdate_mbstring_http_output_conv_mimetypes */
 static PHP_INI_MH(OnUpdate_mbstring_http_output_conv_mimetypes)
 {
-       zval tmp;
+       zend_string *tmp;
        void *re = NULL;
 
        if (!new_value) {
                new_value = entry->orig_value;
        }
-       php_trim(new_value->val, new_value->len, NULL, 0, &tmp, 3);
+       tmp = php_trim(new_value, NULL, 0, 3);
 
-       if (Z_STRLEN(tmp) > 0) {
-               if (!(re = _php_mb_compile_regex(Z_STRVAL(tmp)))) {
-                       zval_dtor(&tmp);
+       if (tmp->len > 0) {
+               if (!(re = _php_mb_compile_regex(tmp->val))) {
+                       zend_string_release(tmp);
                        return FAILURE;
                }
        }
@@ -1458,7 +1458,7 @@ static PHP_INI_MH(OnUpdate_mbstring_http_output_conv_mimetypes)
 
        MBSTRG(http_output_conv_mimetypes) = re;
 
-       zval_dtor(&tmp);
+       zend_string_release(tmp);
        return SUCCESS;
 }
 /* }}} */
index 692b5d368afe61813efebdc7ca8cce91e4ffff77..edaa48ba2241da9aec37abdfe54c5f8b8b4a0387 100644 (file)
@@ -456,7 +456,8 @@ static int sxe_prop_dim_write(zval *object, zval *member, zval *value, zend_bool
        int                             new_value = 0;
        zend_long            cnt = 0;
        int                             retval = SUCCESS;
-       zval            tmp_zv, trim_zv, zval_copy;
+       zval            tmp_zv, zval_copy;
+       zend_string    *trim_str;
 
        sxe = Z_SXEOBJ_P(object);
 
@@ -474,9 +475,9 @@ static int sxe_prop_dim_write(zval *object, zval *member, zval *value, zend_bool
                }
        } else {
                if (Z_TYPE_P(member) != IS_STRING) {
-                       ZVAL_STR(&trim_zv, zval_get_string(member));
-                       php_trim(Z_STRVAL(trim_zv), Z_STRLEN(trim_zv), NULL, 0, &tmp_zv, 3);
-                       zval_dtor(&trim_zv);
+                       trim_str = zval_get_string(member);
+                       ZVAL_STR(&tmp_zv, php_trim(trim_str, NULL, 0, 3));
+                       zend_string_release(trim_str);
                        member = &tmp_zv;
                }
 
index 032c6c7e360f11148fb0eaf6a87e08e3d6daa435..01e3b2cfe4382550d585f280cc2f44fb6c25ef65 100644 (file)
@@ -118,7 +118,7 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper,
        int use_ssl;
        int use_proxy = 0;
        char *scratch = NULL;
-       char *tmp = NULL;
+       zend_string *tmp = NULL;
        char *ua_str = NULL;
        zval *ua_zval = NULL, *tmpzval = NULL, ssl_proxy_peer_name;
        size_t scratch_len = 0;
@@ -440,88 +440,96 @@ finish:
                        smart_str_0(&tmpstr);
                        /* Remove newlines and spaces from start and end. there's at least one extra \r\n at the end that needs to go. */
                        if (tmpstr.s) {
-                               tmp = php_trim(tmpstr.s->val, tmpstr.s->len, NULL, 0, NULL, 3);
+                               tmp = php_trim(tmpstr.s, NULL, 0, 3);
                                smart_str_free(&tmpstr);
                        }
-               }
-               if (Z_TYPE_P(tmpzval) == IS_STRING && Z_STRLEN_P(tmpzval)) {
+               } else if (Z_TYPE_P(tmpzval) == IS_STRING && Z_STRLEN_P(tmpzval)) {
                        /* Remove newlines and spaces from start and end php_trim will estrndup() */
-                       tmp = php_trim(Z_STRVAL_P(tmpzval), Z_STRLEN_P(tmpzval), NULL, 0, NULL, 3);
+                       tmp = php_trim(Z_STR_P(tmpzval), NULL, 0, 3);
                }
-               if (tmp && tmp[0] != '\0') {
+               if (tmp && tmp->len) {
                        char *s;
+                       char *t;
+
+                       user_headers = estrndup(tmp->val, tmp->len);
 
-                       user_headers = estrdup(tmp);
+                       if (IS_INTERNED(tmp)) {
+                               tmp = zend_string_init(tmp->val, tmp->len, 0);
+                       } else if (GC_REFCOUNT(tmp) > 1) {
+                               GC_REFCOUNT(tmp)--;
+                               tmp = zend_string_init(tmp->val, tmp->len, 0);
+                       }
 
                        /* Make lowercase for easy comparison against 'standard' headers */
-                       php_strtolower(tmp, strlen(tmp));
+                       php_strtolower(tmp->val, tmp->len);
+                       t = tmp->val;
 
                        if (!header_init) {
                                /* strip POST headers on redirect */
-                               strip_header(user_headers, tmp, "content-length:");
-                               strip_header(user_headers, tmp, "content-type:");
+                               strip_header(user_headers, t, "content-length:");
+                               strip_header(user_headers, t, "content-type:");
                        }
 
-                       if ((s = strstr(tmp, "user-agent:")) && 
-                           (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || 
+                       if ((s = strstr(t, "user-agent:")) && 
+                           (s == t || *(s-1) == '\r' || *(s-1) == '\n' || 
                                         *(s-1) == '\t' || *(s-1) == ' ')) {
                                 have_header |= HTTP_HEADER_USER_AGENT;
                        }
-                       if ((s = strstr(tmp, "host:")) &&
-                           (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || 
+                       if ((s = strstr(t, "host:")) &&
+                           (s == t || *(s-1) == '\r' || *(s-1) == '\n' || 
                                         *(s-1) == '\t' || *(s-1) == ' ')) {
                                 have_header |= HTTP_HEADER_HOST;
                        }
-                       if ((s = strstr(tmp, "from:")) &&
-                           (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || 
+                       if ((s = strstr(t, "from:")) &&
+                           (s == t || *(s-1) == '\r' || *(s-1) == '\n' || 
                                         *(s-1) == '\t' || *(s-1) == ' ')) {
                                 have_header |= HTTP_HEADER_FROM;
                                }
-                       if ((s = strstr(tmp, "authorization:")) &&
-                           (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || 
+                       if ((s = strstr(t, "authorization:")) &&
+                           (s == t || *(s-1) == '\r' || *(s-1) == '\n' || 
                                         *(s-1) == '\t' || *(s-1) == ' ')) {
                                 have_header |= HTTP_HEADER_AUTH;
                        }
-                       if ((s = strstr(tmp, "content-length:")) &&
-                           (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || 
+                       if ((s = strstr(t, "content-length:")) &&
+                           (s == t || *(s-1) == '\r' || *(s-1) == '\n' || 
                                         *(s-1) == '\t' || *(s-1) == ' ')) {
                                 have_header |= HTTP_HEADER_CONTENT_LENGTH;
                        }
-                       if ((s = strstr(tmp, "content-type:")) &&
-                           (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || 
+                       if ((s = strstr(t, "content-type:")) &&
+                           (s == t || *(s-1) == '\r' || *(s-1) == '\n' || 
                                         *(s-1) == '\t' || *(s-1) == ' ')) {
                                 have_header |= HTTP_HEADER_TYPE;
                        }
-                       if ((s = strstr(tmp, "connection:")) &&
-                           (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || 
+                       if ((s = strstr(t, "connection:")) &&
+                           (s == t || *(s-1) == '\r' || *(s-1) == '\n' || 
                                         *(s-1) == '\t' || *(s-1) == ' ')) {
                                 have_header |= HTTP_HEADER_CONNECTION;
                        }
                        /* remove Proxy-Authorization header */
-                       if (use_proxy && use_ssl && (s = strstr(tmp, "proxy-authorization:")) &&
-                           (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || 
+                       if (use_proxy && use_ssl && (s = strstr(t, "proxy-authorization:")) &&
+                           (s == t || *(s-1) == '\r' || *(s-1) == '\n' || 
                                         *(s-1) == '\t' || *(s-1) == ' ')) {
                                char *p = s + sizeof("proxy-authorization:") - 1;
                                
-                               while (s > tmp && (*(s-1) == ' ' || *(s-1) == '\t')) s--;
+                               while (s > t && (*(s-1) == ' ' || *(s-1) == '\t')) s--;
                                while (*p != 0 && *p != '\r' && *p != '\n') p++;
                                while (*p == '\r' || *p == '\n') p++;
                                if (*p == 0) {
-                                       if (s == tmp) {
+                                       if (s == t) {
                                                efree(user_headers);
                                                user_headers = NULL;
                                        } else {
-                                               while (s > tmp && (*(s-1) == '\r' || *(s-1) == '\n')) s--;
-                                               user_headers[s - tmp] = 0;
+                                               while (s > t && (*(s-1) == '\r' || *(s-1) == '\n')) s--;
+                                               user_headers[s - t] = 0;
                                        }
                                } else {
-                                       memmove(user_headers + (s - tmp), user_headers + (p - tmp), strlen(p) + 1);
+                                       memmove(user_headers + (s - t), user_headers + (p - t), strlen(p) + 1);
                                }
                        }
 
                }
                if (tmp) {
-                       efree(tmp);
+                       zend_string_release(tmp);
                }
        }
 
index 69b80e7baae4ba725a0b9b44dc27151ffd9aad13..e752c042fea594d72cbfd17b8c5ea5277b17ccea 100644 (file)
@@ -100,16 +100,16 @@ PHP_FUNCTION(ezmlm_hash)
    Send an email message */
 PHP_FUNCTION(mail)
 {
-       char *to=NULL, *message=NULL, *headers=NULL, *headers_trimmed=NULL;
+       char *to=NULL, *message=NULL;
        char *subject=NULL;
-       zend_string *extra_cmd=NULL;
-       size_t to_len, message_len, headers_len = 0;
+       zend_string *extra_cmd=NULL, *headers=NULL, *headers_trimmed=NULL;
+       size_t to_len, message_len;
        size_t subject_len, i;
        char *force_extra_parameters = INI_STR("mail.force_extra_parameters");
        char *to_r, *subject_r;
        char *p, *e;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS(), "sss|sS",    &to, &to_len, &subject, &subject_len, &message, &message_len, &headers, &headers_len, &extra_cmd) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS(), "sss|SS",    &to, &to_len, &subject, &subject_len, &message, &message_len, &headers, &extra_cmd) == FAILURE) {
                return;
        }
 
@@ -118,8 +118,8 @@ PHP_FUNCTION(mail)
        MAIL_ASCIIZ_CHECK(subject, subject_len);
        MAIL_ASCIIZ_CHECK(message, message_len);
        if (headers) {
-               MAIL_ASCIIZ_CHECK(headers, headers_len);
-               headers_trimmed = php_trim(headers, headers_len, NULL, 0, NULL, 2);
+               MAIL_ASCIIZ_CHECK(headers->val, headers->len);
+               headers_trimmed = php_trim(headers, NULL, 0, 2);
        }
        if (extra_cmd) {
                MAIL_ASCIIZ_CHECK(extra_cmd->val, extra_cmd->len);
@@ -171,14 +171,14 @@ PHP_FUNCTION(mail)
                extra_cmd = php_escape_shell_cmd(extra_cmd->val);
        }
 
-       if (php_mail(to_r, subject_r, message, headers_trimmed, extra_cmd ? extra_cmd->val : NULL)) {
+       if (php_mail(to_r, subject_r, message, headers_trimmed ? headers_trimmed->val : NULL, extra_cmd ? extra_cmd->val : NULL)) {
                RETVAL_TRUE;
        } else {
                RETVAL_FALSE;
        }
 
        if (headers_trimmed) {
-               efree(headers_trimmed);
+               zend_string_release(headers_trimmed);
        }
 
        if (extra_cmd) {
index c79bfb20fe579f31548a7ec37b3634332c41579e..8e0ad5c97a02c4f4208bbc54392f1ee171a0aab5 100644 (file)
@@ -132,7 +132,7 @@ PHPAPI zend_string *php_str_to_str_ex(char *haystack, size_t length, char *needl
                size_t needle_len, char *str, size_t str_len, int case_sensitivity, size_t *replace_count);
 PHPAPI zend_string *php_str_to_str(char *haystack, size_t length, char *needle,
                size_t needle_len, char *str, size_t str_len);
-PHPAPI char *php_trim(char *c, size_t len, char *what, size_t what_len, zval *return_value, int mode);
+PHPAPI zend_string *php_trim(zend_string *str, char *what, size_t what_len, int mode);
 PHPAPI size_t php_strip_tags(char *rbuf, size_t len, int *state, char *allow, size_t allow_len);
 PHPAPI size_t php_strip_tags_ex(char *rbuf, size_t len, int *stateptr, char *allow, size_t allow_len, zend_bool allow_tag_spaces);
 PHPAPI size_t php_char_to_str_ex(char *str, size_t len, char from, char *to, size_t to_len, zval *result, int case_sensitivity, size_t *replace_count);
index 2668161c09d44bbfe8c945994a2df5152f366561..e275e6456ce6159e9b42e368cc8f49cbae9ea39c 100644 (file)
@@ -788,48 +788,73 @@ static inline int php_charmask(unsigned char *input, size_t len, char *mask)
  * mode 3 : trim left and right
  * what indicates which chars are to be trimmed. NULL->default (' \t\n\r\v\0')
  */
-PHPAPI char *php_trim(char *c, size_t len, char *what, size_t what_len, zval *return_value, int mode)
+PHPAPI zend_string *php_trim(zend_string *str, char *what, size_t what_len, int mode)
 {
+       const char *c = str->val;
+       size_t len = str->len;
        register size_t i;
        size_t trimmed = 0;
        char mask[256];
 
        if (what) {
                php_charmask((unsigned char*)what, what_len, mask);
-       } else {
-               php_charmask((unsigned char*)" \n\r\t\v\0", 6, mask);
-       }
 
-       if (mode & 1) {
-               for (i = 0; i < len; i++) {
-                       if (mask[(unsigned char)c[i]]) {
-                               trimmed++;
-                       } else {
-                               break;
+               if (mode & 1) {
+                       for (i = 0; i < len; i++) {
+                               if (mask[(unsigned char)c[i]]) {
+                                       trimmed++;
+                               } else {
+                                       break;
+                               }
                        }
+                       len -= trimmed;
+                       c += trimmed;
                }
-               len -= trimmed;
-               c += trimmed;
-       }
-       if (mode & 2) {
-               if (len > 0) {
-                       i = len - 1;
-                       do {
-                               if (mask[(unsigned char)c[i]]) {
-                                       len--;
+               if (mode & 2) {
+                       if (len > 0) {
+                               i = len - 1;
+                               do {
+                                       if (mask[(unsigned char)c[i]]) {
+                                               len--;
+                                       } else {
+                                               break;
+                                       }
+                               } while (i-- != 0);
+                       }
+               }
+       } else {
+               if (mode & 1) {
+                       for (i = 0; i < len; i++) {
+                               if ((unsigned char)c[i] <= ' ' &&
+                                   (c[i] == ' ' || c[i] == '\n' || c[i] == '\r' || c[i] == '\t' || c[i] == '\v' || c[i] == '\0')) {
+                                       trimmed++;
                                } else {
                                        break;
                                }
-                       } while (i-- != 0);
+                       }
+                       len -= trimmed;
+                       c += trimmed;
+               }
+               if (mode & 2) {
+                       if (len > 0) {
+                               i = len - 1;
+                               do {
+                                       if ((unsigned char)c[i] <= ' ' &&
+                                           (c[i] == ' ' || c[i] == '\n' || c[i] == '\r' || c[i] == '\t' || c[i] == '\v' || c[i] == '\0')) {
+                                               len--;
+                                       } else {
+                                               break;
+                                       }
+                               } while (i-- != 0);
+                       }
                }
        }
 
-       if (return_value) {
-               RETVAL_STRINGL(c, len);
+       if (str->len == len) {
+               return zend_string_copy(str);
        } else {
-               return estrndup(c, len);
+               return zend_string_init(c, len, 0);
        }
-       return "";
 }
 /* }}} */
 
@@ -853,7 +878,7 @@ static void php_do_trim(INTERNAL_FUNCTION_PARAMETERS, int mode)
        ZEND_PARSE_PARAMETERS_END();
 #endif
 
-       php_trim(str->val, str->len, (what ? what->val : NULL), (what ? what->len : 0), return_value, mode);
+       ZVAL_STR(return_value, php_trim(str, (what ? what->val : NULL), (what ? what->len : 0), mode));
 }
 /* }}} */