diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2021-02-11 10:42:55 +0100 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2021-02-11 15:01:16 +0100 |
commit | 070e24d7a91a49fce56b5ee4d5a102d022d3e724 (patch) | |
tree | d9bd7c9fbf0cba6b62a7f37f5d24ecf2320f90e0 | |
parent | dcf389228c9f1f65da9983226cfe5e6ca6904298 (diff) | |
download | php-git-070e24d7a91a49fce56b5ee4d5a102d022d3e724.tar.gz |
Allow all scalar types in ini_set()
This changes ini_set() to accept all scalar types
(string|int|float|bool|null) for the new value. The idea here is
that while the INI system ultimately works with strings, its value
interpretation is designed to be consistent with PHP's casting rules,
e.g. "1" and "" are interpreted as boolean true and false respectively.
I personally believe that writing ini_set('precision', 10) makes more
sense than ini_set('precision', '10'), and find strict_types to be
unnecessarily pedantic here.
Closes GH-6680.
-rwxr-xr-x | ext/standard/basic_functions.c | 20 | ||||
-rwxr-xr-x | ext/standard/basic_functions.stub.php | 2 | ||||
-rw-r--r-- | ext/standard/basic_functions_arginfo.h | 9 | ||||
-rw-r--r-- | ext/standard/tests/general_functions/ini_set_types.phpt | 34 |
4 files changed, 56 insertions, 9 deletions
diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 54c3188771..4084f5d853 100755 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -2086,14 +2086,19 @@ static int php_ini_check_path(char *option_name, size_t option_len, char *new_op PHP_FUNCTION(ini_set) { zend_string *varname; - zend_string *new_value; + zval *new_value; zend_string *val; ZEND_PARSE_PARAMETERS_START(2, 2) Z_PARAM_STR(varname) - Z_PARAM_STR(new_value) + Z_PARAM_ZVAL(new_value) ZEND_PARSE_PARAMETERS_END(); + if (Z_TYPE_P(new_value) > IS_STRING) { + zend_argument_type_error(2, "must be of type string|int|float|bool|null"); + RETURN_THROWS(); + } + val = zend_ini_get_value(varname); if (val) { @@ -2102,6 +2107,9 @@ PHP_FUNCTION(ini_set) RETVAL_FALSE; } + zend_string *new_value_tmp_str; + zend_string *new_value_str = zval_get_tmp_string(new_value, &new_value_tmp_str); + #define _CHECK_PATH(var, var_len, ini) php_ini_check_path(var, var_len, ini, sizeof(ini)) /* open basedir check */ if (PG(open_basedir)) { @@ -2111,18 +2119,20 @@ PHP_FUNCTION(ini_set) _CHECK_PATH(ZSTR_VAL(varname), ZSTR_LEN(varname), "mail.log") || _CHECK_PATH(ZSTR_VAL(varname), ZSTR_LEN(varname), "java.library.path") || _CHECK_PATH(ZSTR_VAL(varname), ZSTR_LEN(varname), "vpopmail.directory")) { - if (php_check_open_basedir(ZSTR_VAL(new_value))) { + if (php_check_open_basedir(ZSTR_VAL(new_value_str))) { zval_ptr_dtor_str(return_value); + zend_tmp_string_release(new_value_tmp_str); RETURN_FALSE; } } } #undef _CHECK_PATH - if (zend_alter_ini_entry_ex(varname, new_value, PHP_INI_USER, PHP_INI_STAGE_RUNTIME, 0) == FAILURE) { + if (zend_alter_ini_entry_ex(varname, new_value_str, PHP_INI_USER, PHP_INI_STAGE_RUNTIME, 0) == FAILURE) { zval_ptr_dtor_str(return_value); - RETURN_FALSE; + RETVAL_FALSE; } + zend_tmp_string_release(new_value_tmp_str); } /* }}} */ diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index 197af9e3e1..3a7e0de174 100755 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -318,7 +318,7 @@ function ini_get(string $option): string|false {} function ini_get_all(?string $extension = null, bool $details = true): array|false {} -function ini_set(string $option, string $value): string|false {} +function ini_set(string $option, string|int|float|bool|null $value): string|false {} /** @alias ini_set */ function ini_alter(string $option, string $value): string|false {} diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index 514a0338d5..1c7f6b00ec 100644 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 4f4ed195a688735d48aeb3b7cd390d8463a07c26 */ + * Stub hash: e9f39cbc595f0f2cdd84e58d4857f9fdb03ff7b7 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_set_time_limit, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, seconds, IS_LONG, 0) @@ -491,10 +491,13 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_ini_set, 0, 2, MAY_BE_STRING|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, option, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, value, IS_STRING, 0) + ZEND_ARG_TYPE_MASK(0, value, MAY_BE_STRING|MAY_BE_LONG|MAY_BE_DOUBLE|MAY_BE_BOOL|MAY_BE_NULL, NULL) ZEND_END_ARG_INFO() -#define arginfo_ini_alter arginfo_ini_set +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_ini_alter, 0, 2, MAY_BE_STRING|MAY_BE_FALSE) + ZEND_ARG_TYPE_INFO(0, option, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, value, IS_STRING, 0) +ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_ini_restore, 0, 1, IS_VOID, 0) ZEND_ARG_TYPE_INFO(0, option, IS_STRING, 0) diff --git a/ext/standard/tests/general_functions/ini_set_types.phpt b/ext/standard/tests/general_functions/ini_set_types.phpt new file mode 100644 index 0000000000..16def381db --- /dev/null +++ b/ext/standard/tests/general_functions/ini_set_types.phpt @@ -0,0 +1,34 @@ +--TEST-- +ini_set() accepts non-strings under strict_types +--FILE-- +<?php +declare(strict_types=1); + +ini_set('docref_root', null); +var_dump(ini_get('docref_root')); +ini_set('html_errors', true); +var_dump(ini_get('html_errors')); +ini_set('html_errors', false); +var_dump(ini_get('html_errors')); +ini_set('precision', 6); +var_dump(ini_get('precision')); + +// There are no float options in always enabled extensions. +// Just use a random string property, even though it doesn't make sense. +ini_set('user_agent', 3.14); +var_dump(ini_get('user_agent')); + +try { + ini_set('foo', []); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +string(0) "" +string(1) "1" +string(0) "" +string(1) "6" +string(4) "3.14" +ini_set(): Argument #2 ($value) must be of type string|int|float|bool|null |