1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

Fix GH-18823: setlocale's 2nd and 3rd argument ignores strict_types

Closes GH-18828.
This commit is contained in:
Niels Dossche
2025-06-10 20:14:49 +02:00
parent 058c0348fd
commit 43c18f3cfe
5 changed files with 76 additions and 8 deletions

2
NEWS
View File

@@ -250,6 +250,8 @@ PHP NEWS
. Fixed bug GH-18062 (is_callable(func(...), callable_name: $name) for first
class callables returns wrong name). (timwolla)
. Added array_first() and array_last(). (nielsdos)
. Fixed bug GH-18823 (setlocale's 2nd and 3rd argument ignores strict_types).
(nielsdos)
- Streams:
. Fixed bug GH-16889 (stream_select() timeout useless for pipes on Windows).

View File

@@ -4926,37 +4926,52 @@ PHP_FUNCTION(setlocale)
{
zend_long cat;
zval *args = NULL;
int num_args;
uint32_t num_args;
ALLOCA_FLAG(use_heap);
ZEND_PARSE_PARAMETERS_START(2, -1)
Z_PARAM_LONG(cat)
Z_PARAM_VARIADIC('+', args, num_args)
ZEND_PARSE_PARAMETERS_END();
zend_string **strings = do_alloca(sizeof(zend_string *) * num_args, use_heap);
for (uint32_t i = 0; i < num_args; i++) {
if (UNEXPECTED(Z_TYPE(args[i]) != IS_ARRAY && !zend_parse_arg_str(&args[i], &strings[i], false, i + 2))) {
zend_wrong_parameter_type_error(i + 2, Z_EXPECTED_ARRAY_OR_STRING, &args[i]);
goto out;
}
}
for (uint32_t i = 0; i < num_args; i++) {
if (Z_TYPE(args[i]) == IS_ARRAY) {
zval *elem;
ZEND_HASH_FOREACH_VAL(Z_ARRVAL(args[i]), elem) {
zend_string *result = try_setlocale_zval(cat, elem);
if (EG(exception)) {
RETURN_THROWS();
goto out;
}
if (result) {
RETURN_STR(result);
RETVAL_STR(result);
goto out;
}
} ZEND_HASH_FOREACH_END();
} else {
zend_string *result = try_setlocale_zval(cat, &args[i]);
zend_string *result = try_setlocale_str(cat, strings[i]);
if (EG(exception)) {
RETURN_THROWS();
goto out;
}
if (result) {
RETURN_STR(result);
RETVAL_STR(result);
goto out;
}
}
}
RETURN_FALSE;
RETVAL_FALSE;
out:
free_alloca(strings, use_heap);
}
/* }}} */

View File

@@ -0,0 +1,19 @@
--TEST--
GH-18823 (setlocale's 2nd and 3rd argument ignores strict_types) - strict mode
--FILE--
<?php
declare(strict_types=1);
try {
setlocale(LC_ALL, 0, "0");
} catch (TypeError $e) {
echo $e->getMessage(), "\n";
}
try {
setlocale(LC_ALL, "0", 0);
} catch (TypeError $e) {
echo $e->getMessage(), "\n";
}
?>
--EXPECT--
setlocale(): Argument #2 ($locales) must be of type array|string, int given
setlocale(): Argument #3 must be of type array|string, int given

View File

@@ -0,0 +1,32 @@
--TEST--
GH-18823 (setlocale's 2nd and 3rd argument ignores strict_types) - weak mode
--INI--
error_reporting=E_ALL
--FILE--
<?php
class MyStringable {
public function __toString(): string {
return 'foo';
}
}
class MyStringableThrow {
public function __toString(): string {
throw new Error('no');
}
}
setlocale(LC_ALL, 0, "0");
setlocale(LC_ALL, "0", 0);
setlocale(LC_ALL, null);
setlocale(LC_ALL, new MyStringable);
try {
setlocale(LC_ALL, new MyStringableThrow);
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
?>
--EXPECTF--
Deprecated: setlocale(): Passing null to parameter #2 ($locales) of type string is deprecated in %s on line %d
no

View File

@@ -28,7 +28,7 @@ var_dump($locale_info_before);
//Testing setlocale() by giving locale = null
echo "Setting system locale, category = LC_ALL and locale = null\n";
setlocale(LC_ALL, null);
@setlocale(LC_ALL, null);
echo "Locale info, after setting the locale\n";
//Returns Current locale,after executing setlocale().