From: Nikita Popov Date: Mon, 7 Oct 2019 11:04:06 +0000 (+0200) Subject: Warn on strtr(["" => "x"]) X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=93ba3abe63cd339c52cf5774e948bb35d8e73049;p=php 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. --- 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-- + "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"