]> granicus.if.org Git - php/commitdiff
Cleanup (avoid reallocatios and side effects in php_strip_tags)
authorDmitry Stogov <dmitry@zend.com>
Wed, 1 Jul 2015 16:04:18 +0000 (19:04 +0300)
committerDmitry Stogov <dmitry@zend.com>
Wed, 1 Jul 2015 16:04:18 +0000 (19:04 +0300)
Zend/zend_operators.c
Zend/zend_operators.h
ext/standard/file.c
ext/standard/filters.c
ext/standard/php_string.h
ext/standard/string.c

index 1abfcca7a536ace74d1e1e475c12939394c63716..2b90475ba0f3506819eaacad16adf3682c4e9f0d 100644 (file)
@@ -2417,6 +2417,34 @@ ZEND_API void ZEND_FASTCALL zend_str_tolower(char *str, size_t length) /* {{{ */
 }
 /* }}} */
 
+ZEND_API char* ZEND_FASTCALL zend_str_tolower_dup_ex(const char *source, size_t length) /* {{{ */
+{
+       register const unsigned char *p = (const unsigned char*)source;
+       register const unsigned char *end = p + length;
+
+       while (p < end) {
+               if (*p != zend_tolower_ascii(*p)) {
+                       char *res = (char*)emalloc(length + 1);
+                       register unsigned char *r;
+
+                       if (p != (const unsigned char*)source) {
+                               memcpy(res, source, p - (const unsigned char*)source);
+                       }
+                       r = (unsigned char*)p + (res - source);
+                       while (p < end) {
+                               *r = zend_tolower_ascii(*p);
+                               p++;
+                               r++;
+                       }
+                       *r = '\0';
+                       return res;
+               }
+               p++;
+       }
+       return NULL;
+}
+/* }}} */
+
 ZEND_API zend_string* ZEND_FASTCALL zend_string_tolower(zend_string *str) /* {{{ */
 {
        register unsigned char *p = (unsigned char*)ZSTR_VAL(str);
index 601508ca276d2925b3e2fc6f75336a11e28d8f8b..541d6f978fa1d4720bf06f586c2732165e7cf829 100644 (file)
@@ -340,6 +340,7 @@ ZEND_API int string_locale_compare_function(zval *result, zval *op1, zval *op2);
 ZEND_API void         ZEND_FASTCALL zend_str_tolower(char *str, size_t length);
 ZEND_API char*        ZEND_FASTCALL zend_str_tolower_copy(char *dest, const char *source, size_t length);
 ZEND_API char*        ZEND_FASTCALL zend_str_tolower_dup(const char *source, size_t length);
+ZEND_API char*        ZEND_FASTCALL zend_str_tolower_dup_ex(const char *source, size_t length);
 ZEND_API zend_string* ZEND_FASTCALL zend_string_tolower(zend_string *str);
 
 ZEND_API int ZEND_FASTCALL zend_binary_zval_strcmp(zval *s1, zval *s2);
index fc6bf5ae95375e810555577b9fa94babd18a5252..295c1ae1ecf00a7621e3516fc02fdbdee3448b5b 100644 (file)
@@ -1084,11 +1084,10 @@ PHPAPI PHP_FUNCTION(fgetss)
        size_t actual_len, retval_len;
        char *buf = NULL, *retval;
        php_stream *stream;
-       zend_string *allowed = NULL;
        char *allowed_tags=NULL;
        size_t allowed_tags_len=0;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|lS", &fd, &bytes, &allowed) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|ls", &fd, &bytes, &allowed_tags, &allowed_tags_len) == FAILURE) {
                RETURN_FALSE;
        }
 
@@ -1113,24 +1112,8 @@ PHPAPI PHP_FUNCTION(fgetss)
                RETURN_FALSE;
        }
 
-       if (allowed != NULL) {
-// TODO: reimplement to avoid reallocation ???
-               if (ZSTR_IS_INTERNED(allowed)) {
-                       allowed_tags = estrndup(ZSTR_VAL(allowed), ZSTR_LEN(allowed));
-                       allowed_tags_len = ZSTR_LEN(allowed);
-               } else {
-                       allowed_tags = ZSTR_VAL(allowed);
-                       allowed_tags_len = ZSTR_LEN(allowed);
-               }
-       }
-
        retval_len = php_strip_tags(retval, actual_len, &stream->fgetss_state, allowed_tags, allowed_tags_len);
 
-// TODO: reimplement to avoid reallocation ???
-       if (allowed && ZSTR_IS_INTERNED(allowed)) {
-               efree(allowed_tags);
-       }
-
        // TODO: avoid reallocation ???
        RETVAL_STRINGL(retval, retval_len);
        efree(retval);
index 105e156c9e623081712a834a0c3c3adcdc8263c2..3a1f07504002f6622c3bedbfe9311f59441bc214 100644 (file)
@@ -217,7 +217,7 @@ static php_stream_filter_status_t strfilter_strip_tags_filter(
                bucket = php_stream_bucket_make_writeable(buckets_in->head);
                consumed = bucket->buflen;
 
-               bucket->buflen = php_strip_tags(bucket->buf, bucket->buflen, &(inst->state), (char *)inst->allowed_tags, inst->allowed_tags_len);
+               bucket->buflen = php_strip_tags(bucket->buf, bucket->buflen, &(inst->state), inst->allowed_tags, inst->allowed_tags_len);
 
                php_stream_bucket_append(buckets_out, bucket);
        }
index b5cf8f3051754a071a9bde82a241881b9f1767df..8390bd79fefbbecb03e7e02699ec86b5dabcac97 100644 (file)
@@ -133,8 +133,8 @@ PHPAPI char *php_stristr(char *s, char *t, size_t s_len, size_t t_len);
 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 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_strip_tags(char *rbuf, size_t len, int *state, const char *allow, size_t allow_len);
+PHPAPI size_t php_strip_tags_ex(char *rbuf, size_t len, int *stateptr, const char *allow, size_t allow_len, zend_bool allow_tag_spaces);
 PHPAPI void php_implode(const zend_string *delim, zval *arr, zval *return_value);
 PHPAPI void php_explode(const zend_string *delim, zend_string *str, zval *return_value, zend_long limit);
 
index 3a828ed675f819be757fc923698acaf7047a9439..6c436f234f85472f9afa65859e2a92b8329ac097 100644 (file)
@@ -115,7 +115,7 @@ void register_string_constants(INIT_FUNC_ARGS)
 }
 /* }}} */
 
-int php_tag_find(char *tag, size_t len, char *set);
+int php_tag_find(char *tag, size_t len, const char *set);
 
 /* this is read-only, so it's ok */
 static char hexconvtab[] = "0123456789abcdef";
@@ -4451,26 +4451,15 @@ PHP_FUNCTION(strip_tags)
        }
 
        /* To maintain a certain BC, we allow anything for the second parameter and return original string */
-       if (allow != NULL) {
-               convert_to_string_ex(allow);
-// TODO: reimplement to avoid reallocation ???
-               if (!Z_REFCOUNTED_P(allow)) {
-                       allowed_tags = estrndup(Z_STRVAL_P(allow), Z_STRLEN_P(allow));
-                       allowed_tags_len = Z_STRLEN_P(allow);
-               } else {
-                       allowed_tags = Z_STRVAL_P(allow);
-                       allowed_tags_len = Z_STRLEN_P(allow);
-               }
+       if (allow) {
+               convert_to_string(allow);
+               allowed_tags = Z_STRVAL_P(allow);
+               allowed_tags_len = Z_STRLEN_P(allow);
        }
 
        buf = zend_string_init(ZSTR_VAL(str), ZSTR_LEN(str), 0);
        ZSTR_LEN(buf) = php_strip_tags_ex(ZSTR_VAL(buf), ZSTR_LEN(str), NULL, allowed_tags, allowed_tags_len, 0);
-
-// TODO: reimplement to avoid reallocation ???
-       if (allow && !Z_REFCOUNTED_P(allow)) {
-               efree(allowed_tags);
-       }
-       RETURN_STR(buf);
+       RETURN_NEW_STR(buf);
 }
 /* }}} */
 
@@ -4608,7 +4597,7 @@ PHP_FUNCTION(parse_str)
  * 0 start tag
  * 1 first non-whitespace char seen
  */
-int php_tag_find(char *tag, size_t len, char *set) {
+int php_tag_find(char *tag, size_t len, const char *set) {
        char c, *n, *t;
        int state=0, done=0;
        char *norm;
@@ -4663,7 +4652,7 @@ int php_tag_find(char *tag, size_t len, char *set) {
 }
 /* }}} */
 
-PHPAPI size_t php_strip_tags(char *rbuf, size_t len, int *stateptr, char *allow, size_t allow_len) /* {{{ */
+PHPAPI size_t php_strip_tags(char *rbuf, size_t len, int *stateptr, const char *allow, size_t allow_len) /* {{{ */
 {
        return php_strip_tags_ex(rbuf, len, stateptr, allow, allow_len, 0);
 }
@@ -4689,13 +4678,14 @@ PHPAPI size_t php_strip_tags(char *rbuf, size_t len, int *stateptr, char *allow,
        swm: Added ability to strip <?xml tags without assuming it PHP
        code.
 */
-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_strip_tags_ex(char *rbuf, size_t len, int *stateptr, const char *allow, size_t allow_len, zend_bool allow_tag_spaces)
 {
        char *tbuf, *buf, *p, *tp, *rp, c, lc;
        int br, depth=0, in_q = 0;
        int state = 0;
        size_t pos, i = 0;
        char *allow_free = NULL;
+       const char *allow_actual;
 
        if (stateptr)
                state = *stateptr;
@@ -4707,12 +4697,8 @@ PHPAPI size_t php_strip_tags_ex(char *rbuf, size_t len, int *stateptr, char *all
        rp = rbuf;
        br = 0;
        if (allow) {
-//???          if (ZSTR_IS_INTERNED(allow)) {
-//???                  allow_free = allow = zend_str_tolower_dup(allow, allow_len);
-//???          } else {
-                       allow_free = NULL;
-                       php_strtolower(allow, allow_len);
-//???          }
+               allow_free = zend_str_tolower_dup_ex(allow, allow_len);
+               allow_actual = allow_free ? allow_free : allow;
                tbuf = emalloc(PHP_TAG_BUF_SIZE + 1);
                tp = tbuf;
        } else {
@@ -4804,7 +4790,7 @@ PHPAPI size_t php_strip_tags_ex(char *rbuf, size_t len, int *stateptr, char *all
                                                        }
                                                        *(tp++) = '>';
                                                        *tp='\0';
-                                                       if (php_tag_find(tbuf, tp-tbuf, allow)) {
+                                                       if (php_tag_find(tbuf, tp-tbuf, allow_actual)) {
                                                                memcpy(rp, tbuf, tp-tbuf);
                                                                rp += tp-tbuf;
                                                        }