]> granicus.if.org Git - php/commitdiff
Optimized php_addslashes
authorXinchen Hui <laruence@php.net>
Mon, 19 Jan 2015 15:46:39 +0000 (10:46 -0500)
committerXinchen Hui <laruence@php.net>
Mon, 19 Jan 2015 15:46:39 +0000 (10:46 -0500)
ext/filter/sanitizing_filters.c
ext/pcre/php_pcre.c
ext/standard/php_string.h
ext/standard/streamsfuncs.c
ext/standard/string.c

index 59f3b598f72369e3225cc9ec0e1c54c0b713dcd7..d9cb7baeb79e17bce5284b3a31b30d0c3451c3f7 100644 (file)
@@ -373,7 +373,7 @@ void php_filter_magic_quotes(PHP_INPUT_FILTER_PARAM_DECL)
        zend_string *buf;
 
        /* just call php_addslashes quotes */
-       buf = php_addslashes(Z_STRVAL_P(value), Z_STRLEN_P(value), 0);
+       buf = php_addslashes(Z_STR_P(value), 0);
 
        zval_ptr_dtor(value);
        ZVAL_STR(value, buf);
index bb28c2424cf548bcdecdfcdf649125c0d42f5b38..1b3bd8f1de231222c58e41d48a4295714013e860 100644 (file)
@@ -1026,7 +1026,7 @@ static zend_string *preg_do_eval(char *eval_str, int eval_str_len, char *subject
                                        match = subject + offsets[backref<<1];
                                        match_len = offsets[(backref<<1)+1] - offsets[backref<<1];
                                        if (match_len) {
-                                               esc_match = php_addslashes(match, match_len, 0);
+                                               esc_match = php_addslashes_str(match, match_len, 0);
                                        } else {
                                                esc_match = zend_string_init(match, match_len, 0);
                                        }
index 782ab6ee797008ea0727471c73a634ae0d5af370..0e0120e9f172ea32352d2ac76596558e9f5d884c 100644 (file)
@@ -123,7 +123,8 @@ PHPAPI char *php_strtolower(char *s, size_t len);
 PHPAPI zend_string *php_string_toupper(zend_string *s);
 PHPAPI zend_string *php_string_tolower(zend_string *s);
 PHPAPI char *php_strtr(char *str, size_t len, char *str_from, char *str_to, size_t trlen);
-PHPAPI zend_string *php_addslashes(char *str, size_t length, int should_free);
+PHPAPI zend_string *php_addslashes(zend_string *str, int should_free);
+PHPAPI zend_string *php_addslashes_str(const char *str, size_t length, int should_free);
 PHPAPI zend_string *php_addcslashes(const char *str, size_t length, int freeit, char *what, size_t wlength);
 PHPAPI void php_stripslashes(char *str, size_t *len);
 PHPAPI void php_stripcslashes(char *str, size_t *len);
index 839d2a830fdcd60620abc1e71a7e53490fcfd711..d5ee886ee9730212d2c40fdb5434fc8902a3c5ab 100644 (file)
@@ -87,8 +87,7 @@ PHP_FUNCTION(stream_socket_pair)
    Open a client connection to a remote address */
 PHP_FUNCTION(stream_socket_client)
 {
-       char *host;
-       size_t host_len;
+       zend_string *host;
        zval *zerrno = NULL, *zerrstr = NULL, *zcontext = NULL;
        double timeout = (double)FG(default_socket_timeout);
        php_timeout_ull conv;
@@ -102,14 +101,14 @@ PHP_FUNCTION(stream_socket_client)
 
        RETVAL_FALSE;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|z/z/dlr", &host, &host_len, &zerrno, &zerrstr, &timeout, &flags, &zcontext) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|z/z/dlr", &host, &zerrno, &zerrstr, &timeout, &flags, &zcontext) == FAILURE) {
                RETURN_FALSE;
        }
 
        context = php_stream_context_from_zval(zcontext, flags & PHP_FILE_NO_DEFAULT_CONTEXT);
 
        if (flags & PHP_STREAM_CLIENT_PERSISTENT) {
-               spprintf(&hashkey, 0, "stream_socket_client__%s", host);
+               spprintf(&hashkey, 0, "stream_socket_client__%s", host->val);
        }
 
        /* prepare the timeout value for use */
@@ -130,7 +129,7 @@ PHP_FUNCTION(stream_socket_client)
                ZVAL_EMPTY_STRING(zerrstr);
        }
 
-       stream = php_stream_xport_create(host, host_len, REPORT_ERRORS,
+       stream = php_stream_xport_create(host->val, host->len, REPORT_ERRORS,
                        STREAM_XPORT_CLIENT | (flags & PHP_STREAM_CLIENT_CONNECT ? STREAM_XPORT_CONNECT : 0) |
                        (flags & PHP_STREAM_CLIENT_ASYNC_CONNECT ? STREAM_XPORT_CONNECT_ASYNC : 0),
                        hashkey, &tv, context, &errstr, &err);
@@ -138,7 +137,7 @@ PHP_FUNCTION(stream_socket_client)
 
        if (stream == NULL) {
                /* host might contain binary characters */
-               zend_string *quoted_host = php_addslashes(host, host_len, 0);
+               zend_string *quoted_host = php_addslashes(host, 0);
 
                php_error_docref(NULL, E_WARNING, "unable to connect to %s (%s)", quoted_host->val, errstr == NULL ? "Unknown error" : errstr->val);
                zend_string_release(quoted_host);
index a9b4cfe8d0bd6b60220123e56c62fd1a3ee5af16..6848081e1526159bee870d19b0d11f9cf2dfb432 100644 (file)
@@ -3715,7 +3715,7 @@ PHP_FUNCTION(addslashes)
                RETURN_EMPTY_STRING();
        }
 
-       RETURN_STR(php_addslashes(str->val, str->len, 0));
+       RETURN_STR(php_addslashes(str, 0));
 }
 /* }}} */
 
@@ -3882,21 +3882,41 @@ PHPAPI zend_string *php_addcslashes(const char *str, size_t length, int should_f
 
 /* {{{ php_addslashes
  */
-PHPAPI zend_string *php_addslashes(char *str, size_t length, int should_free)
+PHPAPI zend_string *php_addslashes(zend_string *str, int should_free)
 {
        /* maximum string length, worst case situation */
        char *source, *target;
        char *end;
+       size_t offset;
        zend_string *new_str;
 
        if (!str) {
                return STR_EMPTY_ALLOC();
        }
 
-       new_str = zend_string_alloc(2 * (length ? length : (length = strlen(str))), 0);
-       source = str;
-       end = source + length;
-       target = new_str->val;
+       source = str->val;
+       end = source + str->len;
+
+       while (source < end) {
+               switch (*source) {
+                       case '\0':
+                       case '\'':
+                       case '\"':
+                       case '\\':
+                               goto do_escape;
+                       default:
+                               source++;
+                               break;
+               }
+       }
+
+       return zend_string_copy(str);
+
+do_escape:
+       offset = source - (char *)str->val;
+       new_str = zend_string_alloc(offset +  (2 * (str->len - offset)), 0);
+       memcpy(new_str->val, str->val, offset);
+       target = new_str->val + offset;
 
        while (source < end) {
                switch (*source) {
@@ -3919,14 +3939,27 @@ PHPAPI zend_string *php_addslashes(char *str, size_t length, int should_free)
 
        *target = 0;
        if (should_free) {
-               efree(str);
+               zend_string_release(str);
+       }
+
+       if (new_str->len - (target - new_str->val) > 16) {
+               new_str = zend_string_realloc(new_str, target - new_str->val, 0);
+       } else {
+               new_str->len = target - new_str->val;
        }
-       new_str = zend_string_realloc(new_str, target - new_str->val, 0);
 
        return new_str;
 }
 /* }}} */
 
+/* {{{ php_addslashes_str
+ */
+PHPAPI zend_string *php_addslashes_str(const char *str, size_t length, int should_free)
+{
+       return php_addslashes(zend_string_init(str, length, 0), 1);
+}
+/* }}} */
+
 #define _HEB_BLOCK_TYPE_ENG 1
 #define _HEB_BLOCK_TYPE_HEB 2
 #define isheb(c)      (((((unsigned char) c) >= 224) && (((unsigned char) c) <= 250)) ? 1 : 0)