diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2020-03-30 16:06:41 +0200 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2020-03-30 16:15:12 +0200 |
commit | 50d07ff28c9e91f310bf6145b657fccd17b09bec (patch) | |
tree | c212faee882b2fd805db7c36736fca7b67ea5ff9 | |
parent | 47ddd95836142a5bea28abab26999e72d5f85493 (diff) | |
download | php-git-50d07ff28c9e91f310bf6145b657fccd17b09bec.tar.gz |
mb_detect_encoding(): Use proper array|string parameter
Needed to add support for nullabiltiy in some places.
-rw-r--r-- | Zend/zend_API.h | 15 | ||||
-rw-r--r-- | ext/mbstring/mbstring.c | 45 | ||||
-rw-r--r-- | ext/mbstring/mbstring.stub.php | 3 | ||||
-rw-r--r-- | ext/mbstring/mbstring_arginfo.h | 2 | ||||
-rwxr-xr-x | scripts/dev/gen_stub.php | 5 |
5 files changed, 38 insertions, 32 deletions
diff --git a/Zend/zend_API.h b/Zend/zend_API.h index fe5694940c..a925651b83 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -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); diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 1118200cd9..774e6adc7e 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -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; diff --git a/ext/mbstring/mbstring.stub.php b/ext/mbstring/mbstring.stub.php index 67d8468f43..0463f570f4 100644 --- a/ext/mbstring/mbstring.stub.php +++ b/ext/mbstring/mbstring.stub.php @@ -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 {} diff --git a/ext/mbstring/mbstring_arginfo.h b/ext/mbstring/mbstring_arginfo.h index bb902af837..f454cc91e8 100644 --- a/ext/mbstring/mbstring_arginfo.h +++ b/ext/mbstring/mbstring_arginfo.h @@ -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() diff --git a/scripts/dev/gen_stub.php b/scripts/dev/gen_stub.php index 253c188b2a..f3a9a492b0 100755 --- a/scripts/dev/gen_stub.php +++ b/scripts/dev/gen_stub.php @@ -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; |