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:
2
NEWS
2
NEWS
@@ -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).
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
19
ext/standard/tests/strings/gh18823_strict.phpt
Normal file
19
ext/standard/tests/strings/gh18823_strict.phpt
Normal 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
|
||||
32
ext/standard/tests/strings/gh18823_weak.phpt
Normal file
32
ext/standard/tests/strings/gh18823_weak.phpt
Normal 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
|
||||
@@ -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().
|
||||
|
||||
Reference in New Issue
Block a user