]> granicus.if.org Git - php/commitdiff
Fixed bug #68636 (setlocale no longer returns current value per category).
authorDmitry Stogov <dmitry@zend.com>
Thu, 8 Jan 2015 22:41:13 +0000 (01:41 +0300)
committerDmitry Stogov <dmitry@zend.com>
Thu, 8 Jan 2015 22:41:13 +0000 (01:41 +0300)
ext/standard/basic_functions.c
ext/standard/basic_functions.h
ext/standard/string.c
ext/standard/tests/strings/bug68636.phpt [new file with mode: 0644]

index ed5206aa69b73718660f5b36d1c2f0d6f66062fb..02001f543363746248c3810015a710a4c76dd0c2 100644 (file)
@@ -3708,6 +3708,7 @@ PHP_RINIT_FUNCTION(basic) /* {{{ */
        ZVAL_UNDEF(&BG(strtok_zval));
        BG(strtok_last) = NULL;
        BG(locale_string) = NULL;
+       BG(locale_changed) = 0;
        BG(array_walk_fci) = empty_fcall_info;
        BG(array_walk_fci_cache) = empty_fcall_info_cache;
        BG(user_compare_fci) = empty_fcall_info;
@@ -3756,12 +3757,14 @@ PHP_RSHUTDOWN_FUNCTION(basic) /* {{{ */
 
        /* Check if locale was changed and change it back
         * to the value in startup environment */
-       if (BG(locale_string) != NULL) {
+       if (BG(locale_changed)) {
                setlocale(LC_ALL, "C");
                setlocale(LC_CTYPE, "");
                zend_update_current_locale();
-               zend_string_release(BG(locale_string));
-               BG(locale_string) = NULL;
+               if (BG(locale_string)) {
+                       zend_string_release(BG(locale_string));
+                       BG(locale_string) = NULL;
+               }
        }
 
        /* FG(stream_wrappers) and FG(stream_filters) are destroyed
index fe09dc5e257224c24213366caca77fdf4c67e2d7..8820148a63f7ff1c7fca3e7eae73b9ac96addf99 100644 (file)
@@ -168,7 +168,8 @@ typedef struct _php_basic_globals {
        HashTable putenv_ht;
        zval  strtok_zval;
        char *strtok_string;
-       zend_string *locale_string;
+       zend_string *locale_string; /* current LC_CTYPE locale (or NULL for 'C') */
+       zend_bool locale_changed;   /* locale was changed and has to be restored */
        char *strtok_last;
        char strtok_table[256];
        zend_ulong strtok_len;
index c57885fff168cf62a546e93f52250c822a1dac71..483e8b4f1d5ff271859e9c01d0a79a586a0ee86a 100644 (file)
@@ -4343,27 +4343,31 @@ PHP_FUNCTION(setlocale)
                if (retval) {
                        if (loc) {
                                /* Remember if locale was changed */
-                               size_t len;
+                               size_t len = strlen(retval);
 
-                               if (BG(locale_string)) {
-                                       zend_string_release(BG(locale_string));
-                               }
-                               len = strlen(retval);
-                               if (len == loc->len && !memcmp(loc->val, retval, len)) {
-                                       BG(locale_string) = zend_string_copy(loc);
-                               } else {
-                                       BG(locale_string) = zend_string_init(retval, len, 0);
+                               BG(locale_changed) = 1;
+                               if (cat == LC_CTYPE || cat == LC_ALL) {
+                                       if (BG(locale_string)) {
+                                               zend_string_release(BG(locale_string));
+                                       }
+                                       if (len == loc->len && !memcmp(loc->val, retval, len)) {
+                                               BG(locale_string) = zend_string_copy(loc);
+                                               RETURN_STR(BG(locale_string));
+                                       } else {
+                                               BG(locale_string) = zend_string_init(retval, len, 0);
+                                               zend_string_release(loc);
+                                               RETURN_STR(BG(locale_string));
+                                       }
+                               } else if (len == loc->len && !memcmp(loc->val, retval, len)) {
+                                       RETURN_STR(loc);
                                }
-
                                zend_string_release(loc);
                        }
-                       if (BG(locale_string)) {
-                               RETURN_STR(zend_string_copy(BG(locale_string)));
-                       } else {
-                               RETURN_EMPTY_STRING();
-                       }
+                       RETURN_STRING(retval);
+               }
+               if (loc) {
+                       zend_string_release(loc);
                }
-               zend_string_release(loc);
 
                if (Z_TYPE(args[0]) == IS_ARRAY) {
                        if (zend_hash_move_forward_ex(Z_ARRVAL(args[0]), &pos) == FAILURE) break;
diff --git a/ext/standard/tests/strings/bug68636.phpt b/ext/standard/tests/strings/bug68636.phpt
new file mode 100644 (file)
index 0000000..246722c
--- /dev/null
@@ -0,0 +1,21 @@
+--TEST--
+Bug #68636 (setlocale no longer returns current value per category).
+--SKIPIF--
+<?php
+if (substr(PHP_OS, 0, 3) == 'WIN') {
+    die('skip Not valid for windows');
+}
+if (setlocale(LC_ALL, "en_US.UTF8") !== "en_US.UTF8") {
+    die('skip available locales not usable');
+}
+?>
+--FILE--
+<?php
+var_dump(setlocale(LC_TIME, 'en_US.UTF8'));
+var_dump(setlocale(LC_NUMERIC, 'C'));
+var_dump(setlocale(LC_TIME, 0));
+?>
+--EXPECT--
+string(10) "en_US.UTF8"
+string(1) "C"
+string(10) "en_US.UTF8"