Skip to content

Commit 070e24d

Browse files
committed
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.
1 parent dcf3892 commit 070e24d

File tree

4 files changed

+56
-9
lines changed

4 files changed

+56
-9
lines changed

ext/standard/basic_functions.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2086,14 +2086,19 @@ static int php_ini_check_path(char *option_name, size_t option_len, char *new_op
20862086
PHP_FUNCTION(ini_set)
20872087
{
20882088
zend_string *varname;
2089-
zend_string *new_value;
2089+
zval *new_value;
20902090
zend_string *val;
20912091

20922092
ZEND_PARSE_PARAMETERS_START(2, 2)
20932093
Z_PARAM_STR(varname)
2094-
Z_PARAM_STR(new_value)
2094+
Z_PARAM_ZVAL(new_value)
20952095
ZEND_PARSE_PARAMETERS_END();
20962096

2097+
if (Z_TYPE_P(new_value) > IS_STRING) {
2098+
zend_argument_type_error(2, "must be of type string|int|float|bool|null");
2099+
RETURN_THROWS();
2100+
}
2101+
20972102
val = zend_ini_get_value(varname);
20982103

20992104
if (val) {
@@ -2102,6 +2107,9 @@ PHP_FUNCTION(ini_set)
21022107
RETVAL_FALSE;
21032108
}
21042109

2110+
zend_string *new_value_tmp_str;
2111+
zend_string *new_value_str = zval_get_tmp_string(new_value, &new_value_tmp_str);
2112+
21052113
#define _CHECK_PATH(var, var_len, ini) php_ini_check_path(var, var_len, ini, sizeof(ini))
21062114
/* open basedir check */
21072115
if (PG(open_basedir)) {
@@ -2111,18 +2119,20 @@ PHP_FUNCTION(ini_set)
21112119
_CHECK_PATH(ZSTR_VAL(varname), ZSTR_LEN(varname), "mail.log") ||
21122120
_CHECK_PATH(ZSTR_VAL(varname), ZSTR_LEN(varname), "java.library.path") ||
21132121
_CHECK_PATH(ZSTR_VAL(varname), ZSTR_LEN(varname), "vpopmail.directory")) {
2114-
if (php_check_open_basedir(ZSTR_VAL(new_value))) {
2122+
if (php_check_open_basedir(ZSTR_VAL(new_value_str))) {
21152123
zval_ptr_dtor_str(return_value);
2124+
zend_tmp_string_release(new_value_tmp_str);
21162125
RETURN_FALSE;
21172126
}
21182127
}
21192128
}
21202129
#undef _CHECK_PATH
21212130

2122-
if (zend_alter_ini_entry_ex(varname, new_value, PHP_INI_USER, PHP_INI_STAGE_RUNTIME, 0) == FAILURE) {
2131+
if (zend_alter_ini_entry_ex(varname, new_value_str, PHP_INI_USER, PHP_INI_STAGE_RUNTIME, 0) == FAILURE) {
21232132
zval_ptr_dtor_str(return_value);
2124-
RETURN_FALSE;
2133+
RETVAL_FALSE;
21252134
}
2135+
zend_tmp_string_release(new_value_tmp_str);
21262136
}
21272137
/* }}} */
21282138

ext/standard/basic_functions.stub.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ function ini_get(string $option): string|false {}
318318

319319
function ini_get_all(?string $extension = null, bool $details = true): array|false {}
320320

321-
function ini_set(string $option, string $value): string|false {}
321+
function ini_set(string $option, string|int|float|bool|null $value): string|false {}
322322

323323
/** @alias ini_set */
324324
function ini_alter(string $option, string $value): string|false {}

ext/standard/basic_functions_arginfo.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: 4f4ed195a688735d48aeb3b7cd390d8463a07c26 */
2+
* Stub hash: e9f39cbc595f0f2cdd84e58d4857f9fdb03ff7b7 */
33

44
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_set_time_limit, 0, 1, _IS_BOOL, 0)
55
ZEND_ARG_TYPE_INFO(0, seconds, IS_LONG, 0)
@@ -491,10 +491,13 @@ ZEND_END_ARG_INFO()
491491

492492
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_ini_set, 0, 2, MAY_BE_STRING|MAY_BE_FALSE)
493493
ZEND_ARG_TYPE_INFO(0, option, IS_STRING, 0)
494-
ZEND_ARG_TYPE_INFO(0, value, IS_STRING, 0)
494+
ZEND_ARG_TYPE_MASK(0, value, MAY_BE_STRING|MAY_BE_LONG|MAY_BE_DOUBLE|MAY_BE_BOOL|MAY_BE_NULL, NULL)
495495
ZEND_END_ARG_INFO()
496496

497-
#define arginfo_ini_alter arginfo_ini_set
497+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_ini_alter, 0, 2, MAY_BE_STRING|MAY_BE_FALSE)
498+
ZEND_ARG_TYPE_INFO(0, option, IS_STRING, 0)
499+
ZEND_ARG_TYPE_INFO(0, value, IS_STRING, 0)
500+
ZEND_END_ARG_INFO()
498501

499502
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_ini_restore, 0, 1, IS_VOID, 0)
500503
ZEND_ARG_TYPE_INFO(0, option, IS_STRING, 0)
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
--TEST--
2+
ini_set() accepts non-strings under strict_types
3+
--FILE--
4+
<?php
5+
declare(strict_types=1);
6+
7+
ini_set('docref_root', null);
8+
var_dump(ini_get('docref_root'));
9+
ini_set('html_errors', true);
10+
var_dump(ini_get('html_errors'));
11+
ini_set('html_errors', false);
12+
var_dump(ini_get('html_errors'));
13+
ini_set('precision', 6);
14+
var_dump(ini_get('precision'));
15+
16+
// There are no float options in always enabled extensions.
17+
// Just use a random string property, even though it doesn't make sense.
18+
ini_set('user_agent', 3.14);
19+
var_dump(ini_get('user_agent'));
20+
21+
try {
22+
ini_set('foo', []);
23+
} catch (TypeError $e) {
24+
echo $e->getMessage(), "\n";
25+
}
26+
27+
?>
28+
--EXPECT--
29+
string(0) ""
30+
string(1) "1"
31+
string(0) ""
32+
string(1) "6"
33+
string(4) "3.14"
34+
ini_set(): Argument #2 ($value) must be of type string|int|float|bool|null

0 commit comments

Comments
 (0)