]> granicus.if.org Git - php/commitdiff
Convert string|array union parameter types
authorMáté Kocsis <kocsismate@woohoolabs.com>
Mon, 9 Dec 2019 23:03:02 +0000 (00:03 +0100)
committerMáté Kocsis <kocsismate@woohoolabs.com>
Fri, 20 Dec 2019 09:15:52 +0000 (10:15 +0100)
Closes GH-4995

ext/mbstring/mbstring.c
ext/standard/basic_functions.stub.php
ext/standard/basic_functions_arginfo.h
ext/standard/mail.c
ext/standard/php_mail.h
ext/standard/string.c
ext/standard/tests/strings/strtr_variation6.phpt
ext/standard/tests/strings/strtr_variation8.phpt

index 7f92aa2bd00ebb7161b789316b6e4d9b01d484f2..516d4010949cafe933ac32612ace0558eb99512e 100644 (file)
@@ -3929,7 +3929,7 @@ PHP_FUNCTION(mb_send_mail)
                                zend_string_release_ex(tmp_headers, 0);
                                break;
                        case IS_ARRAY:
-                               str_headers = php_mail_build_headers(headers);
+                               str_headers = php_mail_build_headers(Z_ARRVAL_P(headers));
                                break;
                        default:
                                php_error_docref(NULL, E_WARNING, "headers parameter must be string or array");
index db6dfb1c74df68ac22bb274468f650c9038b42ad..f2313ff8317183deda0d62010c8817aa76b568ff 100755 (executable)
@@ -586,10 +586,7 @@ function lcfirst(string $str): string {}
 
 function ucwords(string $str, string $delimiters = " \t\r\n\f\v"): string {}
 
-/**
- * @param string|array $from
- */
-function strtr(string $str, $from, string $to = UNKNOWN): string {}
+function strtr(string $str, string|array $from, string $to = UNKNOWN): string {}
 
 function strrev(string $str): string {}
 
@@ -1015,8 +1012,7 @@ function link(string $target, string $link): bool {}
 
 /* mail.c */
 
-/** @param string|array $additional_headers */
-function mail(string $to, string $subject, string $message, $additional_headers = UNKNOWN, string $additional_parameters = ""): bool {}
+function mail(string $to, string $subject, string $message, string|array $additional_headers = UNKNOWN, string $additional_parameters = ""): bool {}
 
 /* math.c */
 
index d3f0182bdeaab4c72148936ce12a6ad98f2a97ac..816e7c2427a211d22c30b78f51ca73fc9751bc5d 100755 (executable)
@@ -934,7 +934,7 @@ ZEND_END_ARG_INFO()
 
 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_MASK(0, from, MAY_BE_STRING|MAY_BE_ARRAY)
        ZEND_ARG_TYPE_INFO(0, to, IS_STRING, 0)
 ZEND_END_ARG_INFO()
 
@@ -1575,7 +1575,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_mail, 0, 3, _IS_BOOL, 0)
        ZEND_ARG_TYPE_INFO(0, to, IS_STRING, 0)
        ZEND_ARG_TYPE_INFO(0, subject, IS_STRING, 0)
        ZEND_ARG_TYPE_INFO(0, message, IS_STRING, 0)
-       ZEND_ARG_INFO(0, additional_headers)
+       ZEND_ARG_TYPE_MASK(0, additional_headers, MAY_BE_STRING|MAY_BE_ARRAY)
        ZEND_ARG_TYPE_INFO(0, additional_parameters, IS_STRING, 0)
 ZEND_END_ARG_INFO()
 
index b6f987d80f8aefae9681be820ea463c4db1947c1..9e7d9a5b3bd9f29a31945e05a9191c36eb32b460 100644 (file)
@@ -152,16 +152,14 @@ static void php_mail_build_headers_elems(smart_str *s, zend_string *key, zval *v
 }
 
 
-PHPAPI zend_string *php_mail_build_headers(zval *headers)
+PHPAPI zend_string *php_mail_build_headers(HashTable *headers)
 {
        zend_ulong idx;
        zend_string *key;
        zval *val;
        smart_str s = {0};
 
-       ZEND_ASSERT(Z_TYPE_P(headers) == IS_ARRAY);
-
-       ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(headers), idx, key, val) {
+       ZEND_HASH_FOREACH_KEY_VAL(headers, idx, key, val) {
                if (!key) {
                        php_error_docref(NULL, E_WARNING, "Found numeric header (" ZEND_LONG_FMT ")", idx);
                        continue;
@@ -256,8 +254,9 @@ PHP_FUNCTION(mail)
 {
        char *to=NULL, *message=NULL;
        char *subject=NULL;
-       zend_string *extra_cmd=NULL, *str_headers=NULL, *tmp_headers;
-       zval *headers = NULL;
+       zend_string *extra_cmd=NULL;
+       zend_string *headers_str = NULL;
+       HashTable *headers_ht = NULL;
        size_t to_len, message_len;
        size_t subject_len, i;
        char *force_extra_parameters = INI_STR("mail.force_extra_parameters");
@@ -269,7 +268,7 @@ PHP_FUNCTION(mail)
                Z_PARAM_STRING(subject, subject_len)
                Z_PARAM_STRING(message, message_len)
                Z_PARAM_OPTIONAL
-               Z_PARAM_ZVAL(headers)
+               Z_PARAM_STR_OR_ARRAY_HT(headers_str, headers_ht)
                Z_PARAM_STR(extra_cmd)
        ZEND_PARSE_PARAMETERS_END();
 
@@ -277,22 +276,13 @@ PHP_FUNCTION(mail)
        MAIL_ASCIIZ_CHECK(to, to_len);
        MAIL_ASCIIZ_CHECK(subject, subject_len);
        MAIL_ASCIIZ_CHECK(message, message_len);
-       if (headers) {
-               switch(Z_TYPE_P(headers)) {
-                       case IS_STRING:
-                               tmp_headers = zend_string_init(Z_STRVAL_P(headers), Z_STRLEN_P(headers), 0);
-                               MAIL_ASCIIZ_CHECK(ZSTR_VAL(tmp_headers), ZSTR_LEN(tmp_headers));
-                               str_headers = php_trim(tmp_headers, NULL, 0, 2);
-                               zend_string_release_ex(tmp_headers, 0);
-                               break;
-                       case IS_ARRAY:
-                               str_headers = php_mail_build_headers(headers);
-                               break;
-                       default:
-                               php_error_docref(NULL, E_WARNING, "headers parameter must be string or array");
-                               RETURN_FALSE;
-               }
+       if (headers_str) {
+               MAIL_ASCIIZ_CHECK(ZSTR_VAL(headers_str), ZSTR_LEN(headers_str));
+               headers_str = php_trim(headers_str, NULL, 0, 2);
+       } else if (headers_ht) {
+               headers_str = php_mail_build_headers(headers_ht);
        }
+
        if (extra_cmd) {
                MAIL_ASCIIZ_CHECK(ZSTR_VAL(extra_cmd), ZSTR_LEN(extra_cmd));
        }
@@ -343,14 +333,14 @@ PHP_FUNCTION(mail)
                extra_cmd = php_escape_shell_cmd(ZSTR_VAL(extra_cmd));
        }
 
-       if (php_mail(to_r, subject_r, message, str_headers ? ZSTR_VAL(str_headers) : NULL, extra_cmd ? ZSTR_VAL(extra_cmd) : NULL)) {
+       if (php_mail(to_r, subject_r, message, headers_str ? ZSTR_VAL(headers_str) : NULL, extra_cmd ? ZSTR_VAL(extra_cmd) : NULL)) {
                RETVAL_TRUE;
        } else {
                RETVAL_FALSE;
        }
 
-       if (str_headers) {
-               zend_string_release_ex(str_headers, 0);
+       if (headers_str) {
+               zend_string_release_ex(headers_str, 0);
        }
 
        if (extra_cmd) {
index 0e226ba6a1a2efba19e9510e921cfba66e728fb3..29fb5b77f498ee705350ba590d54ff1d17ffb5ac 100644 (file)
@@ -21,7 +21,7 @@ PHP_FUNCTION(mail);
 
 PHP_MINFO_FUNCTION(mail);
 
-PHPAPI zend_string *php_mail_build_headers(zval *headers);
+PHPAPI zend_string *php_mail_build_headers(HashTable *headers);
 PHPAPI extern int php_mail(char *to, char *subject, char *message, char *headers, char *extra_cmd);
 
 #define PHP_MAIL_BUILD_HEADER_CHECK(target, s, key, val) \
index 72b8123d945cb6acbfe7a1bf2b30a208f5d69a8a..1bfbb7044b8d0acdbed96328f8c445ff2f7965c6 100644 (file)
@@ -3236,21 +3236,24 @@ PHPAPI zend_string *php_str_to_str(const char *haystack, size_t length, const ch
    Translates characters in str using given translation tables */
 PHP_FUNCTION(strtr)
 {
-       zval *from;
-       zend_string *str;
+       zend_string *str, *from_str = NULL;
+       HashTable *from_ht = NULL;
        char *to = NULL;
        size_t to_len = 0;
        int ac = ZEND_NUM_ARGS();
 
        ZEND_PARSE_PARAMETERS_START(2, 3)
                Z_PARAM_STR(str)
-               Z_PARAM_ZVAL(from)
+               Z_PARAM_STR_OR_ARRAY_HT(from_str, from_ht)
                Z_PARAM_OPTIONAL
                Z_PARAM_STRING(to, to_len)
        ZEND_PARSE_PARAMETERS_END();
 
-       if (ac == 2 && Z_TYPE_P(from) != IS_ARRAY) {
-               zend_type_error("The second argument is not an array");
+       if (ac == 2 && from_ht == NULL) {
+               zend_type_error("If two arguments are passed, the second argument must be an array");
+               return;
+       } else if (ac != 2 && from_str == NULL) {
+               zend_type_error("If three arguments are passed, the second argument must be a string");
                return;
        }
 
@@ -3260,16 +3263,14 @@ PHP_FUNCTION(strtr)
        }
 
        if (ac == 2) {
-               HashTable *pats = Z_ARRVAL_P(from);
-
-               if (zend_hash_num_elements(pats) < 1) {
+               if (zend_hash_num_elements(from_ht) < 1) {
                        RETURN_STR_COPY(str);
-               } else if (zend_hash_num_elements(pats) == 1) {
+               } else if (zend_hash_num_elements(from_ht) == 1) {
                        zend_long num_key;
                        zend_string *str_key, *tmp_str, *replace, *tmp_replace;
                        zval *entry;
 
-                       ZEND_HASH_FOREACH_KEY_VAL(pats, num_key, str_key, entry) {
+                       ZEND_HASH_FOREACH_KEY_VAL(from_ht, num_key, str_key, entry) {
                                tmp_str = NULL;
                                if (UNEXPECTED(!str_key)) {
                                        str_key = tmp_str = zend_long_to_str(num_key);
@@ -3296,17 +3297,13 @@ PHP_FUNCTION(strtr)
                                return;
                        } ZEND_HASH_FOREACH_END();
                } else {
-                       php_strtr_array(return_value, str, pats);
+                       php_strtr_array(return_value, str, from_ht);
                }
        } else {
-               if (!try_convert_to_string(from)) {
-                       return;
-               }
-
                RETURN_STR(php_strtr_ex(str,
-                                 Z_STRVAL_P(from),
+                                 ZSTR_VAL(from_str),
                                  to,
-                                 MIN(Z_STRLEN_P(from), to_len)));
+                                 MIN(ZSTR_LEN(from_str), to_len)));
        }
 }
 /* }}} */
index 7deffa12fdd73d17b61ac8756e508724e116feef..e0c2458edeeacc640b6a9006deb3d59ff480285c 100644 (file)
@@ -80,8 +80,12 @@ $count = 1;
 for($index = 0; $index < count($from_arr); $index++) {
   echo "-- Iteration $count --\n";
   $from = $from_arr[$index];
-  var_dump( strtr($str, $from, $to) );
-  $count ++;
+  try {
+    var_dump(strtr($str, $from, $to));
+  } catch (TypeError $exception) {
+    echo $exception->getMessage() . "\n";
+  }
+  $count++;
 }
 
 fclose($file_handle);  //closing the file handle
@@ -101,17 +105,11 @@ string(6) "m1tatm"
 -- Iteration 6 --
 string(6) "tm0atm"
 -- Iteration 7 --
-
-Warning: Array to string conversion in %s on line %d
-string(6) "0120tm"
+If three arguments are passed, the second argument must be a string
 -- Iteration 8 --
-
-Warning: Array to string conversion in %s on line %d
-string(6) "0120tm"
+If three arguments are passed, the second argument must be a string
 -- Iteration 9 --
-
-Warning: Array to string conversion in %s on line %d
-string(6) "0120tm"
+If three arguments are passed, the second argument must be a string
 -- Iteration 10 --
 string(6) "0a2atm"
 -- Iteration 11 --
@@ -127,7 +125,7 @@ string(6) "012atm"
 -- Iteration 16 --
 string(6) "012ttm"
 -- Iteration 17 --
-string(6) "012atm"
+strtr() expects parameter 2 to be string or array, resource given
 -- Iteration 18 --
 string(6) "012atm"
 -- Iteration 19 --
index 2e2843335d4777d431d25f996acba5a7c3f5e2a5..97d3163e21f5d730981fc8d9c6124530342af290 100644 (file)
@@ -78,8 +78,8 @@ for($index = 0; $index < count($replace_pairs_arr); $index++) {
     echo "\n-- Iteration $count --\n";
     $replace_pairs = $replace_pairs_arr[$index];
     try {
-        var_dump( strtr($str, $replace_pairs) );
-    } catch (\TypeError $e) {
+        var_dump(strtr($str, $replace_pairs));
+    } catch (TypeError $e) {
         echo $e->getMessage() . "\n";
     }
 
@@ -94,22 +94,22 @@ echo "*** Done ***";
 *** Testing strtr() function: with unexpected inputs for 'replace_pairs' ***
 
 -- Iteration 1 --
-The second argument is not an array
+If two arguments are passed, the second argument must be an array
 
 -- Iteration 2 --
-The second argument is not an array
+If two arguments are passed, the second argument must be an array
 
 -- Iteration 3 --
-The second argument is not an array
+If two arguments are passed, the second argument must be an array
 
 -- Iteration 4 --
-The second argument is not an array
+If two arguments are passed, the second argument must be an array
 
 -- Iteration 5 --
-The second argument is not an array
+If two arguments are passed, the second argument must be an array
 
 -- Iteration 6 --
-The second argument is not an array
+If two arguments are passed, the second argument must be an array
 
 -- Iteration 7 --
 string(6) "012atm"
@@ -121,32 +121,32 @@ string(6) "012atm"
 string(6) "122atm"
 
 -- Iteration 10 --
-The second argument is not an array
+If two arguments are passed, the second argument must be an array
 
 -- Iteration 11 --
-The second argument is not an array
+If two arguments are passed, the second argument must be an array
 
 -- Iteration 12 --
-The second argument is not an array
+If two arguments are passed, the second argument must be an array
 
 -- Iteration 13 --
-The second argument is not an array
+If two arguments are passed, the second argument must be an array
 
 -- Iteration 14 --
-The second argument is not an array
+If two arguments are passed, the second argument must be an array
 
 -- Iteration 15 --
-The second argument is not an array
+If two arguments are passed, the second argument must be an array
 
 -- Iteration 16 --
-The second argument is not an array
+If two arguments are passed, the second argument must be an array
 
 -- Iteration 17 --
-The second argument is not an array
+strtr() expects parameter 2 to be string or array, resource given
 
 -- Iteration 18 --
-The second argument is not an array
+If two arguments are passed, the second argument must be an array
 
 -- Iteration 19 --
-The second argument is not an array
+If two arguments are passed, the second argument must be an array
 *** Done ***