summaryrefslogtreecommitdiff
path: root/ext/standard/string.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/standard/string.c')
-rw-r--r--ext/standard/string.c459
1 files changed, 114 insertions, 345 deletions
diff --git a/ext/standard/string.c b/ext/standard/string.c
index fc234aafad..047f5454d6 100644
--- a/ext/standard/string.c
+++ b/ext/standard/string.c
@@ -1,7 +1,5 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 7 |
- +----------------------------------------------------------------------+
| Copyright (c) The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
@@ -236,15 +234,11 @@ PHP_FUNCTION(bin2hex)
result = php_bin2hex((unsigned char *)ZSTR_VAL(data), ZSTR_LEN(data));
- if (!result) {
- RETURN_FALSE;
- }
-
RETURN_STR(result);
}
/* }}} */
-/* {{{ proto string hex2bin(string data)
+/* {{{ proto string|false hex2bin(string data)
Converts the hex representation of data to binary */
PHP_FUNCTION(hex2bin)
{
@@ -328,7 +322,7 @@ static void php_spn_common_handler(INTERNAL_FUNCTION_PARAMETERS, int behavior) /
}
/* }}} */
-/* {{{ proto int strspn(string str, string mask [, int start [, int len]])
+/* {{{ proto int|false strspn(string str, string mask [, int start [, int len]])
Finds length of initial segment consisting entirely of characters found in mask. If start or/and length is provided works like strspn(substr($s,$start,$len),$good_chars) */
PHP_FUNCTION(strspn)
{
@@ -336,7 +330,7 @@ PHP_FUNCTION(strspn)
}
/* }}} */
-/* {{{ proto int strcspn(string str, string mask [, int start [, int len]])
+/* {{{ proto int|false strcspn(string str, string mask [, int start [, int len]])
Finds length of initial segment consisting entirely of characters not found in mask. If start or/and length is provide works like strcspn(substr($s,$start,$len),$bad_chars) */
PHP_FUNCTION(strcspn)
{
@@ -514,7 +508,7 @@ PHP_MINIT_FUNCTION(nl_langinfo)
}
/* }}} */
-/* {{{ proto string nl_langinfo(int item)
+/* {{{ proto string|false nl_langinfo(int item)
Query language and locale information */
PHP_FUNCTION(nl_langinfo)
{
@@ -937,13 +931,13 @@ PHP_FUNCTION(wordwrap)
}
if (breakchar_len == 0) {
- php_error_docref(NULL, E_WARNING, "Break string cannot be empty");
- RETURN_FALSE;
+ zend_throw_error(NULL, "Break string cannot be empty");
+ return;
}
if (linelength == 0 && docut) {
- php_error_docref(NULL, E_WARNING, "Can't force cut when width is zero");
- RETURN_FALSE;
+ zend_throw_error(NULL, "Can't force cut when width is zero");
+ return;
}
/* Special case for a single-character break as it needs no
@@ -1149,14 +1143,14 @@ PHP_FUNCTION(explode)
ZEND_PARSE_PARAMETERS_END();
if (ZSTR_LEN(delim) == 0) {
- php_error_docref(NULL, E_WARNING, "Empty delimiter");
- RETURN_FALSE;
+ zend_throw_error(NULL, "Empty delimiter");
+ return;
}
array_init(return_value);
if (ZSTR_LEN(str) == 0) {
- if (limit >= 0) {
+ if (limit >= 0) {
ZVAL_EMPTY_STRING(&tmp);
zend_hash_index_add_new(Z_ARRVAL_P(return_value), 0, &tmp);
}
@@ -1281,7 +1275,7 @@ PHP_FUNCTION(implode)
if (arg2 == NULL) {
if (Z_TYPE_P(arg1) != IS_ARRAY) {
- php_error_docref(NULL, E_WARNING, "Argument must be an array");
+ zend_type_error("Argument must be an array");
return;
}
@@ -1298,7 +1292,7 @@ PHP_FUNCTION(implode)
glue = zval_get_tmp_string(arg1, &tmp_glue);
pieces = arg2;
} else {
- php_error_docref(NULL, E_WARNING, "Invalid arguments passed");
+ zend_type_error("Invalid arguments passed");
return;
}
}
@@ -1310,7 +1304,7 @@ PHP_FUNCTION(implode)
#define STRTOK_TABLE(p) BG(strtok_table)[(unsigned char) *p]
-/* {{{ proto string strtok([string str,] string token)
+/* {{{ proto string|false strtok([string str,] string token)
Tokenize a string */
PHP_FUNCTION(strtok)
{
@@ -1648,7 +1642,7 @@ PHP_FUNCTION(dirname)
ZSTR_LEN(ret) = zend_dirname(ZSTR_VAL(ret), str_len);
#endif
} else if (levels < 1) {
- php_error_docref(NULL, E_WARNING, "Invalid argument, levels must be >= 1");
+ zend_throw_error(NULL, "Invalid argument, levels must be >= 1");
zend_string_efree(ret);
return;
} else {
@@ -1666,7 +1660,7 @@ PHP_FUNCTION(dirname)
}
/* }}} */
-/* {{{ proto array pathinfo(string path[, int options])
+/* {{{ proto array|string pathinfo(string path[, int options])
Returns information about a certain string */
PHP_FUNCTION(pathinfo)
{
@@ -1798,76 +1792,28 @@ PHPAPI size_t php_strcspn(char *s1, char *s2, char *s1_end, char *s2_end)
}
/* }}} */
-/* {{{ php_needle_char
- */
-static int php_needle_char(zval *needle, char *target)
-{
- switch (Z_TYPE_P(needle)) {
- case IS_LONG:
- *target = (char)Z_LVAL_P(needle);
- return SUCCESS;
- case IS_NULL:
- case IS_FALSE:
- *target = '\0';
- return SUCCESS;
- case IS_TRUE:
- *target = '\1';
- return SUCCESS;
- case IS_DOUBLE:
- case IS_OBJECT:
- *target = (char) zval_get_long(needle);
- return SUCCESS;
- default:
- php_error_docref(NULL, E_WARNING, "needle is not a string or an integer");
- return FAILURE;
- }
-}
-/* }}} */
-
-/* {{{ proto string stristr(string haystack, string needle[, bool part])
+/* {{{ proto string|false stristr(string haystack, string needle[, bool part])
Finds first occurrence of a string within another, case insensitive */
PHP_FUNCTION(stristr)
{
- zval *needle;
- zend_string *haystack;
+ zend_string *haystack, *needle;
const char *found = NULL;
size_t found_offset;
char *haystack_dup;
- char needle_char[2];
+ char *orig_needle;
zend_bool part = 0;
ZEND_PARSE_PARAMETERS_START(2, 3)
Z_PARAM_STR(haystack)
- Z_PARAM_ZVAL(needle)
+ Z_PARAM_STR(needle)
Z_PARAM_OPTIONAL
Z_PARAM_BOOL(part)
ZEND_PARSE_PARAMETERS_END();
haystack_dup = estrndup(ZSTR_VAL(haystack), ZSTR_LEN(haystack));
-
- if (Z_TYPE_P(needle) == IS_STRING) {
- char *orig_needle;
- if (!Z_STRLEN_P(needle)) {
- php_error_docref(NULL, E_WARNING, "Empty needle");
- efree(haystack_dup);
- RETURN_FALSE;
- }
- orig_needle = estrndup(Z_STRVAL_P(needle), Z_STRLEN_P(needle));
- found = php_stristr(haystack_dup, orig_needle, ZSTR_LEN(haystack), Z_STRLEN_P(needle));
- efree(orig_needle);
- } else {
- if (php_needle_char(needle, needle_char) != SUCCESS) {
- efree(haystack_dup);
- RETURN_FALSE;
- }
- needle_char[1] = 0;
-
- php_error_docref(NULL, E_DEPRECATED,
- "Non-string needles will be interpreted as strings in the future. " \
- "Use an explicit chr() call to preserve the current behavior");
-
- found = php_stristr(haystack_dup, needle_char, ZSTR_LEN(haystack), 1);
- }
+ orig_needle = estrndup(ZSTR_VAL(needle), ZSTR_LEN(needle));
+ found = php_stristr(haystack_dup, orig_needle, ZSTR_LEN(haystack), ZSTR_LEN(needle));
+ efree(orig_needle);
if (found) {
found_offset = found - haystack_dup;
@@ -1884,43 +1830,23 @@ PHP_FUNCTION(stristr)
}
/* }}} */
-/* {{{ proto string strstr(string haystack, string needle[, bool part])
+/* {{{ proto string|false strstr(string haystack, string needle[, bool part])
Finds first occurrence of a string within another */
PHP_FUNCTION(strstr)
{
- zval *needle;
- zend_string *haystack;
+ zend_string *haystack, *needle;
const char *found = NULL;
- char needle_char[2];
zend_long found_offset;
zend_bool part = 0;
ZEND_PARSE_PARAMETERS_START(2, 3)
Z_PARAM_STR(haystack)
- Z_PARAM_ZVAL(needle)
+ Z_PARAM_STR(needle)
Z_PARAM_OPTIONAL
Z_PARAM_BOOL(part)
ZEND_PARSE_PARAMETERS_END();
- if (Z_TYPE_P(needle) == IS_STRING) {
- if (!Z_STRLEN_P(needle)) {
- php_error_docref(NULL, E_WARNING, "Empty needle");
- RETURN_FALSE;
- }
-
- found = php_memnstr(ZSTR_VAL(haystack), Z_STRVAL_P(needle), Z_STRLEN_P(needle), ZSTR_VAL(haystack) + ZSTR_LEN(haystack));
- } else {
- if (php_needle_char(needle, needle_char) != SUCCESS) {
- RETURN_FALSE;
- }
- needle_char[1] = 0;
-
- php_error_docref(NULL, E_DEPRECATED,
- "Non-string needles will be interpreted as strings in the future. " \
- "Use an explicit chr() call to preserve the current behavior");
-
- found = php_memnstr(ZSTR_VAL(haystack), needle_char, 1, ZSTR_VAL(haystack) + ZSTR_LEN(haystack));
- }
+ found = php_memnstr(ZSTR_VAL(haystack), ZSTR_VAL(needle), ZSTR_LEN(needle), ZSTR_VAL(haystack) + ZSTR_LEN(haystack));
if (found) {
found_offset = found - ZSTR_VAL(haystack);
@@ -1938,19 +1864,17 @@ PHP_FUNCTION(strstr)
An alias for strstr */
/* }}} */
-/* {{{ proto int strpos(string haystack, string needle [, int offset])
+/* {{{ proto int|false strpos(string haystack, string needle [, int offset])
Finds position of first occurrence of a string within another */
PHP_FUNCTION(strpos)
{
- zval *needle;
- zend_string *haystack;
+ zend_string *haystack, *needle;
const char *found = NULL;
- char needle_char[2];
- zend_long offset = 0;
+ zend_long offset = 0;
ZEND_PARSE_PARAMETERS_START(2, 3)
Z_PARAM_STR(haystack)
- Z_PARAM_ZVAL(needle)
+ Z_PARAM_STR(needle)
Z_PARAM_OPTIONAL
Z_PARAM_LONG(offset)
ZEND_PARSE_PARAMETERS_END();
@@ -1963,31 +1887,9 @@ PHP_FUNCTION(strpos)
RETURN_FALSE;
}
- if (Z_TYPE_P(needle) == IS_STRING) {
- if (!Z_STRLEN_P(needle)) {
- php_error_docref(NULL, E_WARNING, "Empty needle");
- RETURN_FALSE;
- }
-
- found = (char*)php_memnstr(ZSTR_VAL(haystack) + offset,
- Z_STRVAL_P(needle),
- Z_STRLEN_P(needle),
- ZSTR_VAL(haystack) + ZSTR_LEN(haystack));
- } else {
- if (php_needle_char(needle, needle_char) != SUCCESS) {
- RETURN_FALSE;
- }
- needle_char[1] = 0;
-
- php_error_docref(NULL, E_DEPRECATED,
- "Non-string needles will be interpreted as strings in the future. " \
- "Use an explicit chr() call to preserve the current behavior");
-
- found = (char*)php_memnstr(ZSTR_VAL(haystack) + offset,
- needle_char,
- 1,
- ZSTR_VAL(haystack) + ZSTR_LEN(haystack));
- }
+ found = (char*)php_memnstr(ZSTR_VAL(haystack) + offset,
+ ZSTR_VAL(needle), ZSTR_LEN(needle),
+ ZSTR_VAL(haystack) + ZSTR_LEN(haystack));
if (found) {
RETURN_LONG(found - ZSTR_VAL(haystack));
@@ -1997,20 +1899,18 @@ PHP_FUNCTION(strpos)
}
/* }}} */
-/* {{{ proto int stripos(string haystack, string needle [, int offset])
+/* {{{ proto int|false stripos(string haystack, string needle [, int offset])
Finds position of first occurrence of a string within another, case insensitive */
PHP_FUNCTION(stripos)
{
const char *found = NULL;
- zend_string *haystack;
+ zend_string *haystack, *needle;
zend_long offset = 0;
- char needle_char[2];
- zval *needle;
zend_string *needle_dup = NULL, *haystack_dup;
ZEND_PARSE_PARAMETERS_START(2, 3)
Z_PARAM_STR(haystack)
- Z_PARAM_ZVAL(needle)
+ Z_PARAM_STR(needle)
Z_PARAM_OPTIONAL
Z_PARAM_LONG(offset)
ZEND_PARSE_PARAMETERS_END();
@@ -2023,37 +1923,14 @@ PHP_FUNCTION(stripos)
RETURN_FALSE;
}
- if (ZSTR_LEN(haystack) == 0) {
+ if (ZSTR_LEN(needle) > ZSTR_LEN(haystack)) {
RETURN_FALSE;
}
- if (Z_TYPE_P(needle) == IS_STRING) {
- if (Z_STRLEN_P(needle) == 0 || Z_STRLEN_P(needle) > ZSTR_LEN(haystack)) {
- RETURN_FALSE;
- }
-
- haystack_dup = php_string_tolower(haystack);
- needle_dup = php_string_tolower(Z_STR_P(needle));
- found = (char*)php_memnstr(ZSTR_VAL(haystack_dup) + offset,
- ZSTR_VAL(needle_dup), ZSTR_LEN(needle_dup), ZSTR_VAL(haystack_dup) + ZSTR_LEN(haystack));
- } else {
- if (php_needle_char(needle, needle_char) != SUCCESS) {
- RETURN_FALSE;
- }
-
- php_error_docref(NULL, E_DEPRECATED,
- "Non-string needles will be interpreted as strings in the future. " \
- "Use an explicit chr() call to preserve the current behavior");
-
- haystack_dup = php_string_tolower(haystack);
- needle_char[0] = tolower(needle_char[0]);
- needle_char[1] = '\0';
- found = (char*)php_memnstr(ZSTR_VAL(haystack_dup) + offset,
- needle_char,
- sizeof(needle_char) - 1,
- ZSTR_VAL(haystack_dup) + ZSTR_LEN(haystack));
- }
-
+ haystack_dup = php_string_tolower(haystack);
+ needle_dup = php_string_tolower(needle);
+ found = (char*)php_memnstr(ZSTR_VAL(haystack_dup) + offset,
+ ZSTR_VAL(needle_dup), ZSTR_LEN(needle_dup), ZSTR_VAL(haystack_dup) + ZSTR_LEN(haystack));
if (found) {
RETVAL_LONG(found - ZSTR_VAL(haystack_dup));
@@ -2062,72 +1939,48 @@ PHP_FUNCTION(stripos)
}
zend_string_release_ex(haystack_dup, 0);
- if (needle_dup) {
- zend_string_release_ex(needle_dup, 0);
- }
+ zend_string_release_ex(needle_dup, 0);
}
/* }}} */
-/* {{{ proto int strrpos(string haystack, string needle [, int offset])
+/* {{{ proto int|false strrpos(string haystack, string needle [, int offset])
Finds position of last occurrence of a string within another string */
PHP_FUNCTION(strrpos)
{
- zval *zneedle;
+ zend_string *needle;
zend_string *haystack;
- size_t needle_len;
zend_long offset = 0;
- char ord_needle[2];
- const char *p, *e, *found, *needle;
+ const char *p, *e, *found;
ZEND_PARSE_PARAMETERS_START(2, 3)
Z_PARAM_STR(haystack)
- Z_PARAM_ZVAL(zneedle)
+ Z_PARAM_STR(needle)
Z_PARAM_OPTIONAL
Z_PARAM_LONG(offset)
ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);
- if (Z_TYPE_P(zneedle) == IS_STRING) {
- needle = Z_STRVAL_P(zneedle);
- needle_len = Z_STRLEN_P(zneedle);
- } else {
- if (php_needle_char(zneedle, ord_needle) != SUCCESS) {
- RETURN_FALSE;
- }
-
- php_error_docref(NULL, E_DEPRECATED,
- "Non-string needles will be interpreted as strings in the future. " \
- "Use an explicit chr() call to preserve the current behavior");
-
- ord_needle[1] = '\0';
- needle = ord_needle;
- needle_len = 1;
- }
-
- if ((ZSTR_LEN(haystack) == 0) || (needle_len == 0)) {
- RETURN_FALSE;
- }
-
if (offset >= 0) {
if ((size_t)offset > ZSTR_LEN(haystack)) {
- php_error_docref(NULL, E_WARNING, "Offset is greater than the length of haystack string");
+ php_error_docref(NULL, E_WARNING, "Offset not contained in string");
RETURN_FALSE;
}
p = ZSTR_VAL(haystack) + (size_t)offset;
e = ZSTR_VAL(haystack) + ZSTR_LEN(haystack);
} else {
if (offset < -INT_MAX || (size_t)(-offset) > ZSTR_LEN(haystack)) {
- php_error_docref(NULL, E_WARNING, "Offset is greater than the length of haystack string");
+ php_error_docref(NULL, E_WARNING, "Offset not contained in string");
RETURN_FALSE;
}
+
p = ZSTR_VAL(haystack);
- if ((size_t)-offset < needle_len) {
+ if ((size_t)-offset < ZSTR_LEN(needle)) {
e = ZSTR_VAL(haystack) + ZSTR_LEN(haystack);
} else {
- e = ZSTR_VAL(haystack) + ZSTR_LEN(haystack) + offset + needle_len;
+ e = ZSTR_VAL(haystack) + ZSTR_LEN(haystack) + offset + ZSTR_LEN(needle);
}
}
- if ((found = zend_memnrstr(p, needle, needle_len, e))) {
+ if ((found = zend_memnrstr(p, ZSTR_VAL(needle), ZSTR_LEN(needle), e))) {
RETURN_LONG(found - ZSTR_VAL(haystack));
}
@@ -2135,54 +1988,30 @@ PHP_FUNCTION(strrpos)
}
/* }}} */
-/* {{{ proto int strripos(string haystack, string needle [, int offset])
+/* {{{ proto int|false strripos(string haystack, string needle [, int offset])
Finds position of last occurrence of a string within another string */
PHP_FUNCTION(strripos)
{
- zval *zneedle;
zend_string *needle;
zend_string *haystack;
zend_long offset = 0;
const char *p, *e, *found;
- zend_string *needle_dup, *haystack_dup, *ord_needle = NULL;
- ALLOCA_FLAG(use_heap);
+ zend_string *needle_dup, *haystack_dup;
ZEND_PARSE_PARAMETERS_START(2, 3)
Z_PARAM_STR(haystack)
- Z_PARAM_ZVAL(zneedle)
+ Z_PARAM_STR(needle)
Z_PARAM_OPTIONAL
Z_PARAM_LONG(offset)
ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);
- ZSTR_ALLOCA_ALLOC(ord_needle, 1, use_heap);
- if (Z_TYPE_P(zneedle) == IS_STRING) {
- needle = Z_STR_P(zneedle);
- } else {
- if (php_needle_char(zneedle, ZSTR_VAL(ord_needle)) != SUCCESS) {
- ZSTR_ALLOCA_FREE(ord_needle, use_heap);
- RETURN_FALSE;
- }
-
- php_error_docref(NULL, E_DEPRECATED,
- "Non-string needles will be interpreted as strings in the future. " \
- "Use an explicit chr() call to preserve the current behavior");
-
- ZSTR_VAL(ord_needle)[1] = '\0';
- needle = ord_needle;
- }
-
- if ((ZSTR_LEN(haystack) == 0) || (ZSTR_LEN(needle) == 0)) {
- ZSTR_ALLOCA_FREE(ord_needle, use_heap);
- RETURN_FALSE;
- }
-
if (ZSTR_LEN(needle) == 1) {
/* Single character search can shortcut memcmps
Can also avoid tolower emallocs */
+ char lowered;
if (offset >= 0) {
if ((size_t)offset > ZSTR_LEN(haystack)) {
- ZSTR_ALLOCA_FREE(ord_needle, use_heap);
- php_error_docref(NULL, E_WARNING, "Offset is greater than the length of haystack string");
+ php_error_docref(NULL, E_WARNING, "Offset not contained in string");
RETURN_FALSE;
}
p = ZSTR_VAL(haystack) + (size_t)offset;
@@ -2190,22 +2019,19 @@ PHP_FUNCTION(strripos)
} else {
p = ZSTR_VAL(haystack);
if (offset < -INT_MAX || (size_t)(-offset) > ZSTR_LEN(haystack)) {
- ZSTR_ALLOCA_FREE(ord_needle, use_heap);
- php_error_docref(NULL, E_WARNING, "Offset is greater than the length of haystack string");
+ php_error_docref(NULL, E_WARNING, "Offset not contained in string");
RETURN_FALSE;
}
e = ZSTR_VAL(haystack) + (ZSTR_LEN(haystack) + (size_t)offset);
}
/* Borrow that ord_needle buffer to avoid repeatedly tolower()ing needle */
- *ZSTR_VAL(ord_needle) = tolower(*ZSTR_VAL(needle));
+ lowered = tolower(*ZSTR_VAL(needle));
while (e >= p) {
- if (tolower(*e) == *ZSTR_VAL(ord_needle)) {
- ZSTR_ALLOCA_FREE(ord_needle, use_heap);
+ if (tolower(*e) == lowered) {
RETURN_LONG(e - p + (offset > 0 ? offset : 0));
}
e--;
}
- ZSTR_ALLOCA_FREE(ord_needle, use_heap);
RETURN_FALSE;
}
@@ -2213,8 +2039,7 @@ PHP_FUNCTION(strripos)
if (offset >= 0) {
if ((size_t)offset > ZSTR_LEN(haystack)) {
zend_string_release_ex(haystack_dup, 0);
- ZSTR_ALLOCA_FREE(ord_needle, use_heap);
- php_error_docref(NULL, E_WARNING, "Offset is greater than the length of haystack string");
+ php_error_docref(NULL, E_WARNING, "Offset not contained in string");
RETURN_FALSE;
}
p = ZSTR_VAL(haystack_dup) + offset;
@@ -2222,10 +2047,10 @@ PHP_FUNCTION(strripos)
} else {
if (offset < -INT_MAX || (size_t)(-offset) > ZSTR_LEN(haystack)) {
zend_string_release_ex(haystack_dup, 0);
- ZSTR_ALLOCA_FREE(ord_needle, use_heap);
- php_error_docref(NULL, E_WARNING, "Offset is greater than the length of haystack string");
+ php_error_docref(NULL, E_WARNING, "Offset not contained in string");
RETURN_FALSE;
}
+
p = ZSTR_VAL(haystack_dup);
if ((size_t)-offset < ZSTR_LEN(needle)) {
e = ZSTR_VAL(haystack_dup) + ZSTR_LEN(haystack);
@@ -2239,45 +2064,28 @@ PHP_FUNCTION(strripos)
RETVAL_LONG(found - ZSTR_VAL(haystack_dup));
zend_string_release_ex(needle_dup, 0);
zend_string_release_ex(haystack_dup, 0);
- ZSTR_ALLOCA_FREE(ord_needle, use_heap);
} else {
zend_string_release_ex(needle_dup, 0);
zend_string_release_ex(haystack_dup, 0);
- ZSTR_ALLOCA_FREE(ord_needle, use_heap);
RETURN_FALSE;
}
}
/* }}} */
-/* {{{ proto string strrchr(string haystack, string needle)
+/* {{{ proto string|false strrchr(string haystack, string needle)
Finds the last occurrence of a character in a string within another */
PHP_FUNCTION(strrchr)
{
- zval *needle;
- zend_string *haystack;
+ zend_string *haystack, *needle;
const char *found = NULL;
zend_long found_offset;
ZEND_PARSE_PARAMETERS_START(2, 2)
Z_PARAM_STR(haystack)
- Z_PARAM_ZVAL(needle)
+ Z_PARAM_STR(needle)
ZEND_PARSE_PARAMETERS_END();
- if (Z_TYPE_P(needle) == IS_STRING) {
- found = zend_memrchr(ZSTR_VAL(haystack), *Z_STRVAL_P(needle), ZSTR_LEN(haystack));
- } else {
- char needle_chr;
- if (php_needle_char(needle, &needle_chr) != SUCCESS) {
- RETURN_FALSE;
- }
-
- php_error_docref(NULL, E_DEPRECATED,
- "Non-string needles will be interpreted as strings in the future. " \
- "Use an explicit chr() call to preserve the current behavior");
-
- found = zend_memrchr(ZSTR_VAL(haystack), needle_chr, ZSTR_LEN(haystack));
- }
-
+ found = zend_memrchr(ZSTR_VAL(haystack), *ZSTR_VAL(needle), ZSTR_LEN(haystack));
if (found) {
found_offset = found - ZSTR_VAL(haystack);
RETURN_STRINGL(found, ZSTR_LEN(haystack) - found_offset);
@@ -2293,28 +2101,19 @@ static zend_string *php_chunk_split(const char *src, size_t srclen, const char *
{
char *q;
const char *p;
- size_t chunks; /* complete chunks! */
+ size_t chunks;
size_t restlen;
- size_t out_len;
zend_string *dest;
chunks = srclen / chunklen;
restlen = srclen - chunks * chunklen; /* srclen % chunklen */
-
- if (chunks > INT_MAX - 1) {
- return NULL;
- }
- out_len = chunks + 1;
- if (endlen !=0 && out_len > INT_MAX/endlen) {
- return NULL;
- }
- out_len *= endlen;
- if (out_len > INT_MAX - srclen - 1) {
- return NULL;
+ if (restlen) {
+ /* We want chunks to be rounded up rather than rounded down.
+ * Increment can't overflow because chunks <= SIZE_MAX/2 at this point. */
+ chunks++;
}
- out_len += srclen + 1;
- dest = zend_string_alloc(out_len * sizeof(char), 0);
+ dest = zend_string_safe_alloc(chunks, endlen, srclen, 0);
for (p = src, q = ZSTR_VAL(dest); p < (src + srclen - chunklen + 1); ) {
memcpy(q, p, chunklen);
@@ -2332,7 +2131,7 @@ static zend_string *php_chunk_split(const char *src, size_t srclen, const char *
}
*q = '\0';
- ZSTR_LEN(dest) = q - ZSTR_VAL(dest);
+ ZEND_ASSERT(q - ZSTR_VAL(dest) == ZSTR_LEN(dest));
return dest;
}
@@ -2356,8 +2155,8 @@ PHP_FUNCTION(chunk_split)
ZEND_PARSE_PARAMETERS_END();
if (chunklen <= 0) {
- php_error_docref(NULL, E_WARNING, "Chunk length should be greater than zero");
- RETURN_FALSE;
+ zend_throw_error(NULL, "Chunk length should be greater than zero");
+ return;
}
if ((size_t)chunklen > ZSTR_LEN(str)) {
@@ -2375,15 +2174,11 @@ PHP_FUNCTION(chunk_split)
result = php_chunk_split(ZSTR_VAL(str), ZSTR_LEN(str), end, endlen, (size_t)chunklen);
- if (result) {
- RETURN_STR(result);
- } else {
- RETURN_FALSE;
- }
+ RETURN_STR(result);
}
/* }}} */
-/* {{{ proto string substr(string str, int start [, int length])
+/* {{{ proto string|false substr(string str, int start [, int length])
Returns part of a string */
PHP_FUNCTION(substr)
{
@@ -2459,7 +2254,7 @@ truncate_len:
}
/* }}} */
-/* {{{ proto mixed substr_replace(mixed str, mixed repl, mixed start [, mixed length])
+/* {{{ proto string|array|false substr_replace(mixed str, mixed repl, mixed start [, mixed length])
Replaces part of a string with another string */
PHP_FUNCTION(substr_replace)
{
@@ -2739,8 +2534,8 @@ PHP_FUNCTION(quotemeta)
old_end = ZSTR_VAL(old) + ZSTR_LEN(old);
- if (ZSTR_VAL(old) == old_end) {
- RETURN_FALSE;
+ if (ZSTR_LEN(old) == 0) {
+ RETURN_EMPTY_STRING();
}
str = zend_string_safe_alloc(2, ZSTR_LEN(old), 0, 0);
@@ -2796,7 +2591,7 @@ PHP_FUNCTION(chr)
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_LONG(c)
- ZEND_PARSE_PARAMETERS_END_EX(c = 0);
+ ZEND_PARSE_PARAMETERS_END();
c &= 0xff;
ZVAL_INTERNED_STR(return_value, ZSTR_CHAR(c));
@@ -3473,8 +3268,8 @@ PHP_FUNCTION(strtr)
ZEND_PARSE_PARAMETERS_END();
if (ac == 2 && Z_TYPE_P(from) != IS_ARRAY) {
- php_error_docref(NULL, E_WARNING, "The second argument is not an array");
- RETURN_FALSE;
+ zend_type_error("The second argument is not an array");
+ return;
}
/* shortcut for empty string */
@@ -4616,7 +4411,7 @@ static void php_hebrev(INTERNAL_FUNCTION_PARAMETERS, int convert_newlines)
ZEND_PARSE_PARAMETERS_END();
if (str_len == 0) {
- RETURN_FALSE;
+ RETURN_EMPTY_STRING();
}
tmp = str;
@@ -4916,7 +4711,7 @@ PHP_FUNCTION(strip_tags)
}
/* }}} */
-/* {{{ proto string setlocale(mixed category, string locale [, string ...])
+/* {{{ proto string|false setlocale(mixed category, string locale [, string ...])
Set locale information */
PHP_FUNCTION(setlocale)
{
@@ -5029,7 +4824,7 @@ PHP_FUNCTION(setlocale)
}
/* }}} */
-/* {{{ proto void parse_str(string encoded_string [, array &result])
+/* {{{ proto void parse_str(string encoded_string, array &result)
Parses GET/POST/COOKIE data and sets global variables */
PHP_FUNCTION(parse_str)
{
@@ -5038,39 +4833,18 @@ PHP_FUNCTION(parse_str)
char *res = NULL;
size_t arglen;
- ZEND_PARSE_PARAMETERS_START(1, 2)
+ ZEND_PARSE_PARAMETERS_START(2, 2)
Z_PARAM_STRING(arg, arglen)
- Z_PARAM_OPTIONAL
Z_PARAM_ZVAL(arrayArg)
ZEND_PARSE_PARAMETERS_END();
- res = estrndup(arg, arglen);
-
- if (arrayArg == NULL) {
- zval tmp;
- zend_array *symbol_table;
- if (zend_forbid_dynamic_call("parse_str() with a single argument") == FAILURE) {
- efree(res);
- return;
- }
-
- php_error_docref(NULL, E_DEPRECATED, "Calling parse_str() without the result argument is deprecated");
-
- symbol_table = zend_rebuild_symbol_table();
- ZVAL_ARR(&tmp, symbol_table);
- sapi_module.treat_data(PARSE_STRING, res, &tmp);
- if (UNEXPECTED(zend_hash_del(symbol_table, ZSTR_KNOWN(ZEND_STR_THIS)) == SUCCESS)) {
- zend_throw_error(NULL, "Cannot re-assign $this");
- }
- } else {
- arrayArg = zend_try_array_init(arrayArg);
- if (!arrayArg) {
- efree(res);
- return;
- }
-
- sapi_module.treat_data(PARSE_STRING, res, arrayArg);
+ arrayArg = zend_try_array_init(arrayArg);
+ if (!arrayArg) {
+ return;
}
+
+ res = estrndup(arg, arglen);
+ sapi_module.treat_data(PARSE_STRING, res, arrayArg);
}
/* }}} */
@@ -5547,7 +5321,7 @@ PHP_FUNCTION(str_repeat)
ZEND_PARSE_PARAMETERS_END();
if (mult < 0) {
- php_error_docref(NULL, E_WARNING, "Second argument has to be greater than or equal to 0");
+ zend_throw_error(NULL, "Second argument has to be greater than or equal to 0");
return;
}
@@ -5585,7 +5359,7 @@ PHP_FUNCTION(str_repeat)
}
/* }}} */
-/* {{{ proto mixed count_chars(string input [, int mode])
+/* {{{ proto array|string|false count_chars(string input [, int mode])
Returns info about what characters are used in input */
PHP_FUNCTION(count_chars)
{
@@ -5773,7 +5547,7 @@ PHP_FUNCTION(strnatcasecmp)
}
/* }}} */
-/* {{{ proto int substr_count(string haystack, string needle [, int offset [, int length]])
+/* {{{ proto int|false substr_count(string haystack, string needle [, int offset [, int length]])
Returns the number of times a substring occurs in the string */
PHP_FUNCTION(substr_count)
{
@@ -5794,8 +5568,8 @@ PHP_FUNCTION(substr_count)
ZEND_PARSE_PARAMETERS_END();
if (needle_len == 0) {
- php_error_docref(NULL, E_WARNING, "Empty substring");
- RETURN_FALSE;
+ zend_throw_error(NULL, "Empty substring");
+ return;
}
p = haystack;
@@ -5871,21 +5645,16 @@ PHP_FUNCTION(str_pad)
}
if (pad_str_len == 0) {
- php_error_docref(NULL, E_WARNING, "Padding string cannot be empty");
+ zend_throw_error(NULL, "Padding string cannot be empty");
return;
}
if (pad_type_val < STR_PAD_LEFT || pad_type_val > STR_PAD_BOTH) {
- php_error_docref(NULL, E_WARNING, "Padding type has to be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH");
+ zend_throw_error(NULL, "Padding type has to be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH");
return;
}
num_pad_chars = pad_length - ZSTR_LEN(input);
- if (num_pad_chars >= INT_MAX) {
- php_error_docref(NULL, E_WARNING, "Padding length is too long");
- return;
- }
-
result = zend_string_safe_alloc(1, ZSTR_LEN(input), num_pad_chars, 0);
ZSTR_LEN(result) = 0;
@@ -6083,7 +5852,7 @@ static void php_string_shuffle(char *str, zend_long len) /* {{{ */
}
/* }}} */
-/* {{{ proto void str_shuffle(string str)
+/* {{{ proto string str_shuffle(string str)
Shuffles string. One permutation of all possible is created */
PHP_FUNCTION(str_shuffle)
{
@@ -6100,13 +5869,13 @@ PHP_FUNCTION(str_shuffle)
}
/* }}} */
-/* {{{ proto mixed str_word_count(string str, [int format [, string charlist]])
+
+/* {{{ proto array|int str_word_count(string str, [int format [, string charlist]])
Counts the number of words inside a string. If format of 1 is specified,
then the function will return an array containing all the words
found inside the string. If format of 2 is specified, then the function
will return an associated array where the position of the word is the key
and the word itself is the value.
-
For the purpose of this function, 'word' is defined as a locale dependent
string containing alphabetic characters, which also may contain, but not start
with "'" and "-" characters.
@@ -6141,8 +5910,8 @@ PHP_FUNCTION(str_word_count)
/* nothing to be done */
break;
default:
- php_error_docref(NULL, E_WARNING, "Invalid format value " ZEND_LONG_FMT, type);
- RETURN_FALSE;
+ zend_throw_error(NULL, "Invalid format value " ZEND_LONG_FMT, type);
+ return;
}
if (char_list) {
@@ -6191,7 +5960,7 @@ PHP_FUNCTION(str_word_count)
/* }}} */
#if HAVE_STRFMON
-/* {{{ proto string money_format(string format , float value)
+/* {{{ proto string|false money_format(string format , float value)
Convert monetary value(s) to string */
PHP_FUNCTION(money_format)
{
@@ -6258,8 +6027,8 @@ PHP_FUNCTION(str_split)
ZEND_PARSE_PARAMETERS_END();
if (split_length <= 0) {
- php_error_docref(NULL, E_WARNING, "The length of each segment must be greater than zero");
- RETURN_FALSE;
+ zend_throw_error(NULL, "The length of each segment must be greater than zero");
+ return;
}
@@ -6285,7 +6054,7 @@ PHP_FUNCTION(str_split)
}
/* }}} */
-/* {{{ proto array strpbrk(string haystack, string char_list)
+/* {{{ proto string|false strpbrk(string haystack, string char_list)
Search a string for any of a set of characters */
PHP_FUNCTION(strpbrk)
{
@@ -6314,7 +6083,7 @@ PHP_FUNCTION(strpbrk)
}
/* }}} */
-/* {{{ proto int substr_compare(string main_str, string str, int offset [, int length [, bool case_sensitivity]])
+/* {{{ proto int|false substr_compare(string main_str, string str, int offset [, int length [, bool case_sensitivity]])
Binary safe optionally case insensitive comparison of 2 strings from an offset, up to length characters */
PHP_FUNCTION(substr_compare)
{
@@ -6337,8 +6106,8 @@ PHP_FUNCTION(substr_compare)
if (len == 0) {
RETURN_LONG(0L);
} else {
- php_error_docref(NULL, E_WARNING, "The length must be greater than or equal to zero");
- RETURN_FALSE;
+ zend_throw_error(NULL, "The length must be greater than or equal to zero");
+ return;
}
}