summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-10-07 13:04:06 +0200
committerNikita Popov <nikita.ppv@gmail.com>2019-10-30 10:53:45 +0100
commit93ba3abe63cd339c52cf5774e948bb35d8e73049 (patch)
tree4a7d1e418c79fb9cd8276a6816a07a4c5a7594e5 /ext
parentbecda2e0418d4efb55fca40b1170ca67cfbdb4e0 (diff)
downloadphp-git-93ba3abe63cd339c52cf5774e948bb35d8e73049.tar.gz
Warn on strtr(["" => "x"])
Previously: * If only ["" => "x"] was present, the original string was returned without warning. * If both ["" => "x"] and at least one more element was present, false was returned without warning. New behavior: * Ignore "" keys in the replacement array (and perform any remaining replacement). * Throw a warning indicating that an empty string replacement has been ignored. Closes GH-4792.
Diffstat (limited to 'ext')
-rwxr-xr-xext/standard/basic_functions.stub.php3
-rwxr-xr-xext/standard/basic_functions_arginfo.h2
-rw-r--r--ext/standard/string.c5
-rw-r--r--ext/standard/tests/strings/strtr_empty_search_string.phpt15
4 files changed, 20 insertions, 5 deletions
diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php
index 8e0a2cde6b..de4d22bc3c 100755
--- a/ext/standard/basic_functions.stub.php
+++ b/ext/standard/basic_functions.stub.php
@@ -499,9 +499,8 @@ function ucwords(string $str, string $delimiters = " \t\r\n\f\v"): string {}
/**
* @param string|array $from
- * @return string|false
*/
-function strtr(string $str, $from, string $to = UNKNOWN) {}
+function strtr(string $str, $from, string $to = UNKNOWN): string {}
function strrev(string $str): string {}
diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h
index 24735d679f..103b44f152 100755
--- a/ext/standard/basic_functions_arginfo.h
+++ b/ext/standard/basic_functions_arginfo.h
@@ -659,7 +659,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_ucwords, 0, 1, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, delimiters, IS_STRING, 0)
ZEND_END_ARG_INFO()
-ZEND_BEGIN_ARG_INFO_EX(arginfo_strtr, 0, 0, 2)
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_strtr, 0, 2, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, str, IS_STRING, 0)
ZEND_ARG_INFO(0, from)
ZEND_ARG_TYPE_INFO(0, to, IS_STRING, 0)
diff --git a/ext/standard/string.c b/ext/standard/string.c
index 639e443c06..a23c85c6d3 100644
--- a/ext/standard/string.c
+++ b/ext/standard/string.c
@@ -2819,8 +2819,8 @@ static void php_strtr_array(zval *return_value, zend_string *input, HashTable *p
} else {
len = ZSTR_LEN(str_key);
if (UNEXPECTED(len < 1)) {
- efree(num_bitset);
- RETURN_FALSE;
+ php_error_docref(NULL, E_WARNING, "Ignoring replacement of empty string");
+ continue;
} else if (UNEXPECTED(len > slen)) {
/* skip long patterns */
continue;
@@ -3294,6 +3294,7 @@ PHP_FUNCTION(strtr)
}
replace = zval_get_tmp_string(entry, &tmp_replace);
if (ZSTR_LEN(str_key) < 1) {
+ php_error_docref(NULL, E_WARNING, "Ignoring replacement of empty string");
RETVAL_STR_COPY(str);
} else if (ZSTR_LEN(str_key) == 1) {
RETVAL_STR(php_char_to_str_ex(str,
diff --git a/ext/standard/tests/strings/strtr_empty_search_string.phpt b/ext/standard/tests/strings/strtr_empty_search_string.phpt
new file mode 100644
index 0000000000..3c861600ff
--- /dev/null
+++ b/ext/standard/tests/strings/strtr_empty_search_string.phpt
@@ -0,0 +1,15 @@
+--TEST--
+strtr() trying to replace an empty string
+--FILE--
+<?php
+
+var_dump(strtr("foo", ["" => "bar"]));
+var_dump(strtr("foo", ["" => "bar", "x" => "y"]));
+
+?>
+--EXPECTF--
+Warning: strtr(): Ignoring replacement of empty string in %s on line %d
+string(3) "foo"
+
+Warning: strtr(): Ignoring replacement of empty string in %s on line %d
+string(3) "foo"