Skip to content

Ensure ctype_string is NULL for C locale #5542

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

Closed
wants to merge 1 commit into from
Closed

Conversation

nikic
Copy link
Member

@nikic nikic commented May 7, 2020

We already document that BG(ctype_locale) is NULL for C locale:

zend_string *ctype_string; /* current LC_CTYPE locale (or NULL for 'C') */

This change makes sure that this is always the case, even if setlocale() is explicitly called with "C" locale. Now BG(ctype_local) != NULL can be used as a quick check whether the C locale is used.

@@ -1462,7 +1462,7 @@ PHPAPI zend_string *php_string_tolower(zend_string *s)
unsigned char *c;
const unsigned char *e;

if (EXPECTED(!BG(locale_changed))) {
if (EXPECTED(!BG(ctype_string))) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated: What's the reasoning for performing this operation for strtolower() but not strtoupper()?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because there is no zend_string_toupper :) We only perform ASCII lowercase internally.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense

@@ -4801,7 +4801,12 @@ PHP_FUNCTION(setlocale)
if (BG(ctype_string)) {
zend_string_release_ex(BG(ctype_string), 0);
}
if (len == ZSTR_LEN(loc) && !memcmp(ZSTR_VAL(loc), retval, len)) {
if (len == 1 && *retval == 'C') {
Copy link
Contributor

@TysonAndre TysonAndre May 7, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fairly certain that retval was the original locale, not the new locale. - setlocale() and php_my_setlocale() return the original locale if it changed.

This should check ZSTR_VAL(loc) instead, e.g. zend_string_equals_literal(locale, "C")

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setlocale() returns the locale that was set, not the previous one. This is necessary because it may not be the same as what was passed to the setlocale() call, e.g. when using "" environment locale.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, good. I was mixed up with other C and PHP APIs that did that - the c code is returning the new locale

https://en.cppreference.com/w/c/locale/setlocale
https://www.php.net/manual/en/function.setlocale.php#refsect1-function.setlocale-returnvalues

Copy link
Contributor

@TysonAndre TysonAndre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM if related tests pass

@nikic
Copy link
Member Author

nikic commented May 7, 2020

AppVeyor failure is unrelated (and maybe fixed by d38f819, we'll see...)

@php-pulls php-pulls closed this in 2414b3d May 7, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants