diff options
author | Matt Wilmas <mattwil@php.net> | 2009-04-01 17:05:36 +0000 |
---|---|---|
committer | Matt Wilmas <mattwil@php.net> | 2009-04-01 17:05:36 +0000 |
commit | c27bf17f634a7cb1397b9ca5e1a8f63fb25dc4f4 (patch) | |
tree | 2400fc78254afb1385187ca5cc27888dfaab0182 | |
parent | dc683c85f4f219f0d58b03bd1eaf0bfbe959176e (diff) | |
download | php-git-c27bf17f634a7cb1397b9ca5e1a8f63fb25dc4f4.tar.gz |
MFH: explode() stuff:
- Fixed bug #47560 (explode()'s limit parameter odd behaviour) by reverting change for bug #47546
- Changed int to long where needed (should fix memory errors from overflow seen in bug #47854)
- Simplified logic a bit with limit and its default value
- php_explode_negative_limit(): removed safe_emalloc (not needed; plain erealloc is used later)
- Moved declarations/allocation to optimize if the delimiter isn't found
- Changed ALLOC_STEP size for less realloc's (and maybe better memory block alignment?)
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | ext/standard/php_string.h | 2 | ||||
-rw-r--r-- | ext/standard/string.c | 30 | ||||
-rw-r--r-- | ext/standard/tests/strings/bug47546.phpt | 24 |
4 files changed, 17 insertions, 40 deletions
@@ -18,6 +18,7 @@ PHP NEWS crashes). (Dmitry) - Fixed bug #47699 (autoload and late static binding). (Dmitry) - Fixed bug #47596 (Bus error on parsing file). (Dmitry) +- Fixed bug #47560 (explode()'s limit parameter odd behaviour). (Matt) - Fixed bug #47516 (nowdoc can not be embed in heredoc but can be embed in double quote). (Dmitry) - Fixed bug #47038 (Memory leak in include). (Dmitry) diff --git a/ext/standard/php_string.h b/ext/standard/php_string.h index ba03aeee5f..526c04954d 100644 --- a/ext/standard/php_string.h +++ b/ext/standard/php_string.h @@ -138,7 +138,7 @@ PHPAPI size_t php_strip_tags_ex(char *rbuf, int len, int *stateptr, char *allow, PHPAPI int php_char_to_str_ex(char *str, uint len, char from, char *to, int to_len, zval *result, int case_sensitivity, int *replace_count); PHPAPI int php_char_to_str(char *str, uint len, char from, char *to, int to_len, zval *result); PHPAPI void php_implode(zval *delim, zval *arr, zval *return_value TSRMLS_DC); -PHPAPI void php_explode(zval *delim, zval *str, zval *return_value, int limit); +PHPAPI void php_explode(zval *delim, zval *str, zval *return_value, long limit); PHPAPI size_t php_strspn(char *s1, char *s2, char *s1_end, char *s2_end); PHPAPI size_t php_strcspn(char *s1, char *s2, char *s1_end, char *s2_end); diff --git a/ext/standard/string.c b/ext/standard/string.c index 61a6fbf622..1c772c043e 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -928,7 +928,7 @@ PHP_FUNCTION(wordwrap) /* {{{ php_explode */ -PHPAPI void php_explode(zval *delim, zval *str, zval *return_value, int limit) +PHPAPI void php_explode(zval *delim, zval *str, zval *return_value, long limit) { char *p1, *p2, *endp; @@ -944,7 +944,7 @@ PHPAPI void php_explode(zval *delim, zval *str, zval *return_value, int limit) add_next_index_stringl(return_value, p1, p2 - p1, 1); p1 = p2 + Z_STRLEN_P(delim); } while ((p2 = php_memnstr(p1, Z_STRVAL_P(delim), Z_STRLEN_P(delim), endp)) != NULL && - (limit == -1 || --limit > 1)); + --limit > 1); if (p1 <= endp) add_next_index_stringl(return_value, p1, endp-p1, 1); @@ -954,12 +954,10 @@ PHPAPI void php_explode(zval *delim, zval *str, zval *return_value, int limit) /* {{{ php_explode_negative_limit */ -PHPAPI void php_explode_negative_limit(zval *delim, zval *str, zval *return_value, int limit) +PHPAPI void php_explode_negative_limit(zval *delim, zval *str, zval *return_value, long limit) { -#define EXPLODE_ALLOC_STEP 50 +#define EXPLODE_ALLOC_STEP 64 char *p1, *p2, *endp; - int allocated = EXPLODE_ALLOC_STEP, found = 0, i = 0, to_return = 0; - char **positions = safe_emalloc(allocated, sizeof(char *), 0); endp = Z_STRVAL_P(str) + Z_STRLEN_P(str); @@ -972,6 +970,10 @@ PHPAPI void php_explode_negative_limit(zval *delim, zval *str, zval *return_valu by doing nothing we return empty array */ } else { + int allocated = EXPLODE_ALLOC_STEP, found = 0; + long i, to_return; + char **positions = emalloc(allocated * sizeof(char *)); + positions[found++] = p1; do { if (found >= allocated) { @@ -989,8 +991,8 @@ PHPAPI void php_explode_negative_limit(zval *delim, zval *str, zval *return_valu 1 ); } + efree(positions); } - efree(positions); #undef EXPLODE_ALLOC_STEP } /* }}} */ @@ -1000,8 +1002,7 @@ PHPAPI void php_explode_negative_limit(zval *delim, zval *str, zval *return_valu PHP_FUNCTION(explode) { zval **str, **delim; - long limit = -1; - int argc = ZEND_NUM_ARGS(); + long limit = LONG_MAX; /* No limit */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ|l", &delim, &str, &limit) == FAILURE) { return; @@ -1018,19 +1019,18 @@ PHP_FUNCTION(explode) array_init(return_value); if (! Z_STRLEN_PP(str)) { - if (limit >= 0 || argc == 2) { + if (limit >= 0) { add_next_index_stringl(return_value, "", sizeof("") - 1, 1); } return; } - - if (limit == 0 || limit == 1) { - add_index_stringl(return_value, 0, Z_STRVAL_PP(str), Z_STRLEN_PP(str), 1); - } else if (limit < -1 && argc == 3) { + if (limit > 1) { + php_explode(*delim, *str, return_value, limit); + } else if (limit < 0) { php_explode_negative_limit(*delim, *str, return_value, limit); } else { - php_explode(*delim, *str, return_value, limit); + add_index_stringl(return_value, 0, Z_STRVAL_PP(str), Z_STRLEN_PP(str), 1); } } /* }}} */ diff --git a/ext/standard/tests/strings/bug47546.phpt b/ext/standard/tests/strings/bug47546.phpt deleted file mode 100644 index f04f9be05a..0000000000 --- a/ext/standard/tests/strings/bug47546.phpt +++ /dev/null @@ -1,24 +0,0 @@ ---TEST-- -Bug #47546 (Default value for limit parameter in explode is 0, not -1) ---FILE-- -<?php -$str = 'one|two|three|four'; - -print_r(explode('|', $str)); -print_r(explode('|', $str, -1)); -?> ---EXPECT-- -Array -( - [0] => one - [1] => two - [2] => three - [3] => four -) -Array -( - [0] => one - [1] => two - [2] => three - [3] => four -) |