summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2021-02-11 10:42:55 +0100
committerNikita Popov <nikita.ppv@gmail.com>2021-02-11 15:01:16 +0100
commit070e24d7a91a49fce56b5ee4d5a102d022d3e724 (patch)
treed9bd7c9fbf0cba6b62a7f37f5d24ecf2320f90e0
parentdcf389228c9f1f65da9983226cfe5e6ca6904298 (diff)
downloadphp-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-xext/standard/basic_functions.c20
-rwxr-xr-xext/standard/basic_functions.stub.php2
-rw-r--r--ext/standard/basic_functions_arginfo.h9
-rw-r--r--ext/standard/tests/general_functions/ini_set_types.phpt34
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