-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Fix GH-18823: setlocale's 2nd and 3rd argument ignores strict_types #18828
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Nitpick, don't use u32, use size_t. |
The argument count is 32-bits. |
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.
I believe promotion rules turn it into an unsigned number, but indeed should be unsigned. I'll change it |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't cover all cases.
For some other references:
- Why we don't mess with values within arrays with strict_types: Notice and Warning promotion in ext/zip #5823 (comment)
- We could warn if the array doesn't strictly hold a string: Check parameters on compact() and throw TypeError if not string or array of strings #6921
ext/standard/string.c
Outdated
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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. |
No description provided.