Browse Source

Fixed bug #68636 (setlocale no longer returns current value per category).

pull/986/merge
Dmitry Stogov 11 years ago
parent
commit
7b4808a647
  1. 9
      ext/standard/basic_functions.c
  2. 3
      ext/standard/basic_functions.h
  3. 36
      ext/standard/string.c
  4. 21
      ext/standard/tests/strings/bug68636.phpt

9
ext/standard/basic_functions.c

@ -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

3
ext/standard/basic_functions.h

@ -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;

36
ext/standard/string.c

@ -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;

21
ext/standard/tests/strings/bug68636.phpt

@ -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"
Loading…
Cancel
Save