]> granicus.if.org Git - php/commitdiff
Warn on strtr(["" => "x"])
authorNikita Popov <nikita.ppv@gmail.com>
Mon, 7 Oct 2019 11:04:06 +0000 (13:04 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Wed, 30 Oct 2019 09:53:45 +0000 (10:53 +0100)
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.

ext/standard/basic_functions.stub.php
ext/standard/basic_functions_arginfo.h
ext/standard/string.c
ext/standard/tests/strings/strtr_empty_search_string.phpt [new file with mode: 0644]

index 8e0a2cde6b0c0dda13debc1fff383c7d332b87ee..de4d22bc3cea199f1fe4cb0b4e2610f9667be115 100755 (executable)
@@ -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 {}
 
index 24735d679ff3f34b84776305db9493ae629f0b55..103b44f1526a82ab70ad44a6d7e54db9053f2fe0 100755 (executable)
@@ -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)
index 639e443c066ce7b21e88dea265114c15432f5f5d..a23c85c6d3632a849af50ab97f2078110eb44afa 100644 (file)
@@ -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 (file)
index 0000000..3c86160
--- /dev/null
@@ -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"