]> granicus.if.org Git - php/commitdiff
Ensure ctype_string is NULL for C locale
authorNikita Popov <nikita.ppv@gmail.com>
Thu, 7 May 2020 16:50:42 +0000 (18:50 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Thu, 7 May 2020 19:26:13 +0000 (21:26 +0200)
We already document that this is the case, but currently it's only
true if setlocale() has not been called. Make sure ctype_string is
always NULL, even with an explicit "C" locale call, so we can
more efficiently check whether we are in the "C" locale.

Closes GH-5542.

ext/pcre/php_pcre.c
ext/standard/string.c

index 611a18bd48bc9c8b3e7faea7f6ae1b7d58e73ff3..9f67bff14cc95c2f8a4465525eec908a5e9b76f8 100644 (file)
@@ -595,8 +595,7 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, in
        zend_string             *key;
        pcre_cache_entry *ret;
 
-       if (locale_aware && BG(ctype_string) &&
-               (ZSTR_LEN(BG(ctype_string)) != 1 && ZSTR_VAL(BG(ctype_string))[0] != 'C')) {
+       if (locale_aware && BG(ctype_string)) {
                key = zend_string_concat2(
                        ZSTR_VAL(BG(ctype_string)), ZSTR_LEN(BG(ctype_string)),
                        ZSTR_VAL(regex), ZSTR_LEN(regex));
index 93ad0062442ddbf898b049bcc821fbd531215424..7729acf4512144a6c6dddd024edfee3b4d845ca8 100644 (file)
@@ -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))) {
                return zend_string_tolower(s);
        } else {
                c = (unsigned char *)ZSTR_VAL(s);
@@ -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') {
+                                               /* C locale is represented as NULL. */
+                                               BG(ctype_string) = NULL;
+                                               zend_string_release_ex(loc, 0);
+                                               RETURN_INTERNED_STR(ZSTR_CHAR('C'));
+                                       } else if (len == ZSTR_LEN(loc) && !memcmp(ZSTR_VAL(loc), retval, len)) {
                                                BG(ctype_string) = zend_string_copy(loc);
                                                RETURN_STR(BG(ctype_string));
                                        } else {