]> granicus.if.org Git - php/commitdiff
mb_detect_encoding(): Use proper array|string parameter
authorNikita Popov <nikita.ppv@gmail.com>
Mon, 30 Mar 2020 14:06:41 +0000 (16:06 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Mon, 30 Mar 2020 14:15:12 +0000 (16:15 +0200)
Needed to add support for nullabiltiy in some places.

Zend/zend_API.h
ext/mbstring/mbstring.c
ext/mbstring/mbstring.stub.php
ext/mbstring/mbstring_arginfo.h
scripts/dev/gen_stub.php

index fe5694940c1d2dd7d1d0ce456eaa6d03ba1fed39..a925651b83c2a9cd109cc032af3c08b0c8bf104a 100644 (file)
@@ -1548,14 +1548,20 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_value_error(uint32_t arg_num
 #define Z_PARAM_VARIADIC(spec, dest, dest_num) \
        Z_PARAM_VARIADIC_EX(spec, dest, dest_num, 0)
 
-#define Z_PARAM_STR_OR_ARRAY_HT(dest_str, dest_ht) \
+#define Z_PARAM_STR_OR_ARRAY_HT_EX(dest_str, dest_ht, allow_null) \
        Z_PARAM_PROLOGUE(0, 0); \
-       if (UNEXPECTED(!zend_parse_arg_str_or_array_ht(_arg, &dest_str, &dest_ht))) { \
+       if (UNEXPECTED(!zend_parse_arg_str_or_array_ht(_arg, &dest_str, &dest_ht, allow_null))) { \
                _expected_type = Z_EXPECTED_STRING_OR_ARRAY; \
                _error_code = ZPP_ERROR_WRONG_ARG; \
                break; \
        }
 
+#define Z_PARAM_STR_OR_ARRAY_HT(dest_str, dest_ht) \
+       Z_PARAM_STR_OR_ARRAY_HT_EX(dest_str, dest_ht, 0);
+
+#define Z_PARAM_STR_OR_ARRAY_HT_OR_NULL(dest_str, dest_ht) \
+       Z_PARAM_STR_OR_ARRAY_HT_EX(dest_str, dest_ht, 1);
+
 /* End of new parameter parsing API */
 
 /* Inlined implementations shared by new and old parameter parsing APIs */
@@ -1775,7 +1781,7 @@ static zend_always_inline void zend_parse_arg_zval_deref(zval *arg, zval **dest,
 }
 
 static zend_always_inline int zend_parse_arg_str_or_array_ht(
-               zval *arg, zend_string **dest_str, HashTable **dest_ht)
+               zval *arg, zend_string **dest_str, HashTable **dest_ht, int allow_null)
 {
        if (EXPECTED(Z_TYPE_P(arg) == IS_STRING)) {
                *dest_str = Z_STR_P(arg);
@@ -1783,6 +1789,9 @@ static zend_always_inline int zend_parse_arg_str_or_array_ht(
        } else if (EXPECTED(Z_TYPE_P(arg) == IS_ARRAY)) {
                *dest_ht = Z_ARRVAL_P(arg);
                *dest_str = NULL;
+       } else if (allow_null && EXPECTED(Z_TYPE_P(arg) == IS_NULL)) {
+               *dest_ht = NULL;
+               *dest_str = NULL;
        } else {
                *dest_ht = NULL;
                return zend_parse_arg_str_slow(arg, dest_str);
index 1118200cd9cc0ffba79850aa977933042a885487..774e6adc7e494dd4a716943d00c4c62d23fa778e 100644 (file)
@@ -2961,8 +2961,9 @@ PHP_FUNCTION(mb_detect_encoding)
 {
        char *str;
        size_t str_len;
-       zend_bool strict=0;
-       zval *encoding_list = NULL;
+       zend_string *encoding_str = NULL;
+       HashTable *encoding_ht = NULL;
+       zend_bool strict = 0;
 
        mbfl_string string;
        const mbfl_encoding *ret;
@@ -2970,30 +2971,21 @@ PHP_FUNCTION(mb_detect_encoding)
        size_t size;
        zend_bool free_elist;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|z!b", &str, &str_len, &encoding_list, &strict) == FAILURE) {
-               RETURN_THROWS();
-       }
+       ZEND_PARSE_PARAMETERS_START(1, 3)
+               Z_PARAM_STRING(str, str_len)
+               Z_PARAM_OPTIONAL
+               Z_PARAM_STR_OR_ARRAY_HT_OR_NULL(encoding_str, encoding_ht)
+               Z_PARAM_BOOL(strict)
+       ZEND_PARSE_PARAMETERS_END();
 
        /* make encoding list */
-       if (encoding_list) {
-               switch (Z_TYPE_P(encoding_list)) {
-               case IS_ARRAY:
-                       if (FAILURE == php_mb_parse_encoding_array(Z_ARRVAL_P(encoding_list), &elist, &size, 0)) {
-                               RETURN_FALSE;
-                       }
-                       break;
-               default:
-                       if (!try_convert_to_string(encoding_list)) {
-                               RETURN_THROWS();
-                       }
-                       if (FAILURE == php_mb_parse_encoding_list(Z_STRVAL_P(encoding_list), Z_STRLEN_P(encoding_list), &elist, &size, 0)) {
-                               RETURN_FALSE;
-                       }
-                       break;
+       if (encoding_ht) {
+               if (FAILURE == php_mb_parse_encoding_array(encoding_ht, &elist, &size, 0)) {
+                       RETURN_FALSE;
                }
-               if (size == 0) {
-                       efree(elist);
-                       php_error_docref(NULL, E_WARNING, "Must specify at least one encoding");
+               free_elist = 1;
+       } else if (encoding_str) {
+               if (FAILURE == php_mb_parse_encoding_list(ZSTR_VAL(encoding_str), ZSTR_LEN(encoding_str), &elist, &size, 0)) {
                        RETURN_FALSE;
                }
                free_elist = 1;
@@ -3003,11 +2995,16 @@ PHP_FUNCTION(mb_detect_encoding)
                free_elist = 0;
        }
 
+       if (size == 0) {
+               efree(elist);
+               php_error_docref(NULL, E_WARNING, "Must specify at least one encoding");
+               RETURN_FALSE;
+       }
+
        if (ZEND_NUM_ARGS() < 3) {
                strict = MBSTRG(strict_detection);
        }
 
-
        mbfl_string_init(&string);
        string.no_language = MBSTRG(language);
        string.val = (unsigned char *)str;
index 67d8468f430098d76d4bfeac93c2fe9a34964f78..0463f570f447e60f8d6139b8d4e906b555d8d79e 100644 (file)
@@ -56,8 +56,7 @@ function mb_strtoupper(string $sourcestring, ?string $encoding = null): string|f
 
 function mb_strtolower(string $sourcestring, ?string $encoding = null): string|false {}
 
-/** @param array|string $encoding_list */
-function mb_detect_encoding(string $str, $encoding_list = null, bool $strict = false): string|false {}
+function mb_detect_encoding(string $str, array|string|null $encoding_list = null, bool $strict = false): string|false {}
 
 function mb_list_encodings(): array {}
 
index bb902af837d9933954ae100faf37494ac6e98728..f454cc91e8ea9a3a963121ec4b74ee2e4a63811c 100644 (file)
@@ -124,7 +124,7 @@ ZEND_END_ARG_INFO()
 
 ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_mb_detect_encoding, 0, 1, MAY_BE_STRING|MAY_BE_FALSE)
        ZEND_ARG_TYPE_INFO(0, str, IS_STRING, 0)
-       ZEND_ARG_INFO(0, encoding_list)
+       ZEND_ARG_TYPE_MASK(0, encoding_list, MAY_BE_ARRAY|MAY_BE_STRING|MAY_BE_NULL)
        ZEND_ARG_TYPE_INFO(0, strict, _IS_BOOL, 0)
 ZEND_END_ARG_INFO()
 
index 253c188b2ac977b0ac91119f6aafecfbdfefb5d9..f3a9a492b0c67df94b380d02b246a3b5497b0670 100755 (executable)
@@ -373,9 +373,10 @@ function parseFunctionLike(string $name, Node\FunctionLike $func, ?string $cond)
             throw new Exception("Error in function $name: only the last parameter can be variadic");
         }
 
+        $type = $param->type ? Type::fromNode($param->type) : null;
         if ($param->default instanceof Expr\ConstFetch &&
             $param->default->name->toLowerString() === "null" &&
-            $param->type && !($param->type instanceof Node\NullableType)
+            $type && !$type->isNullable()
         ) {
             throw new Exception(
                 "Parameter $varName of function $name has null default, but is not nullable");
@@ -387,7 +388,7 @@ function parseFunctionLike(string $name, Node\FunctionLike $func, ?string $cond)
             $varName,
             $sendBy,
             $param->variadic,
-            $param->type ? Type::fromNode($param->type) : null
+            $type
         );
         if (!$param->default && !$param->variadic) {
             $numRequiredArgs = $i + 1;