summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Wilmas <mattwil@php.net>2009-04-01 17:05:36 +0000
committerMatt Wilmas <mattwil@php.net>2009-04-01 17:05:36 +0000
commitc27bf17f634a7cb1397b9ca5e1a8f63fb25dc4f4 (patch)
tree2400fc78254afb1385187ca5cc27888dfaab0182
parentdc683c85f4f219f0d58b03bd1eaf0bfbe959176e (diff)
downloadphp-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--NEWS1
-rw-r--r--ext/standard/php_string.h2
-rw-r--r--ext/standard/string.c30
-rw-r--r--ext/standard/tests/strings/bug47546.phpt24
4 files changed, 17 insertions, 40 deletions
diff --git a/NEWS b/NEWS
index b6af37b279..98c2a338a8 100644
--- a/NEWS
+++ b/NEWS
@@ -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
-)