Uh oh!
There was an error while loading. Please reload this page.
Fix GH-18823: setlocale's 2nd and 3rd argument ignores strict_types - #18828
Fix GH-18823: setlocale's 2nd and 3rd argument ignores strict_types#18828ndossche wants to merge 4 commits into
Conversation
Nitpick, don't use u32, use size_t. |
ndossche
commented
Jun 10, 2025
The argument count is 32-bits. |
divinity76
commented
Jun 10, 2025
Reminds me of a famous quote attributed to Bill Gates,
Ok nevermind. Code LGTM! |
This comment was marked as outdated.
This comment was marked as outdated.
ndossche
commented
Jun 10, 2025
I believe promotion rules turn it into an unsigned number, but indeed should be unsigned. I'll change it |
DanielEScherzer
left a comment
There was a problem hiding this comment.
My reading of https://www.php.net/manual/en/function.setlocale.php is that you can either use
setlocale(int $category, string $locales, string ...$rest)where argument 2, 3, etc. are stringssetlocale(int $category, array $locale_array)where argument 2 is an array and there is no argument 3
and so I would expect error for the third argument to just say string, not array|string.
But, looking at the code it appears that any of the subsequent parameters can be an array - is that correct, and the documentation is wrong? Or is that unintended?
Should the types of the values in the array also be checked?
Any arg can be an array here so the docs are simply wrong. We should change the docs to match the C sources because we consider the C sources as the source of truth. |
Girgias
left a comment
There was a problem hiding this comment.
This doesn't cover all cases.
For some other references:
- Why we don't mess with values within arrays with strict_types: #5823 (comment)
- We could warn if the array doesn't strictly hold a string: #6921
| if (ZEND_ARG_USES_STRICT_TYPES()) { | ||
| for (uint32_t i = 0; i < num_args; i++) { | ||
| if (UNEXPECTED(Z_TYPE(args[i]) != IS_ARRAY && Z_TYPE(args[i]) != IS_STRING)) { | ||
| zend_wrong_parameter_type_error(i + 2, Z_EXPECTED_ARRAY_OR_STRING, &args[i]); | ||
| RETURN_THROWS(); | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
This doesn't cover the case where a non-stringable object is passed as argument, nor a resource, or null. (in weak mode)
There was a problem hiding this comment.
I first was confused by your comment, but you mean the coercions in weak mode are not done a priori and thus there is also no proper error handling of that.
I suppose we can call zend_parse_arg_str ourselves and do the coercions upfront instead of in try_setlocale_zval.
There was a problem hiding this comment.
That and also types that should be rejected by our normal semantics were not :)
Test fails on arm, probably because of weak mode coercion changes, probably due to the deprecation now being emitted and the diff algorithm also seems confused as usual. |
remicollet
commented
Jul 8, 2025
NULL needs to be allowed for the second parameter, reported as #19070 |
No description provided.