diff options
author | Anatol Belski <ab@php.net> | 2014-12-06 11:59:43 +0100 |
---|---|---|
committer | Anatol Belski <ab@php.net> | 2014-12-06 11:59:43 +0100 |
commit | 1b4d5ad46a60401bb3db754b4ef6888a7285e637 (patch) | |
tree | 0f32497547dd60278673d8bfb8ce00c3a7cc8305 | |
parent | 625b929c6eb222773d175bd22a7b893165b960fd (diff) | |
download | php-git-1b4d5ad46a60401bb3db754b4ef6888a7285e637.tar.gz |
Fixed bug #65230 setting locale randomly broken
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | ext/standard/formatted_print.c | 16 | ||||
-rw-r--r-- | ext/standard/tests/strings/bug65230.phpt | 60 | ||||
-rw-r--r-- | main/snprintf.c | 16 | ||||
-rw-r--r-- | main/spprintf.c | 16 | ||||
-rw-r--r-- | tests/lang/034.phpt | 4 | ||||
-rw-r--r-- | tests/lang/bug30638.phpt | 4 |
7 files changed, 109 insertions, 8 deletions
@@ -10,6 +10,7 @@ PHP NEWS (Anatol) . Fixed bug #68297 (Application Popup provides too few information). (Anatol) . Fixed bug #65769 (localeconv() broken in TS builds). (Anatol) + . Fixed bug #65230 (setting locale randomly broken). (Anatol) - cURL: . Fixed bug #67643 (curl_multi_getcontent returns '' when diff --git a/ext/standard/formatted_print.c b/ext/standard/formatted_print.c index 2592b1655d..a21bfebe42 100644 --- a/ext/standard/formatted_print.c +++ b/ext/standard/formatted_print.c @@ -27,7 +27,11 @@ #ifdef HAVE_LOCALE_H #include <locale.h> +#ifdef ZTS +#define LCONV_DECIMAL_POINT (*lconv.decimal_point) +#else #define LCONV_DECIMAL_POINT (*lconv->decimal_point) +#endif #else #define LCONV_DECIMAL_POINT '.' #endif @@ -214,8 +218,12 @@ php_sprintf_appenddouble(char **buffer, int *pos, char *s = NULL; int s_len = 0, is_negative = 0; #ifdef HAVE_LOCALE_H +#ifdef ZTS + struct lconv lconv; +#else struct lconv *lconv; #endif +#endif PRINTF_DEBUG(("sprintf: appenddouble(%x, %x, %x, %f, %d, '%c', %d, %c)\n", *buffer, pos, size, number, width, padding, alignment, fmt)); @@ -246,8 +254,12 @@ php_sprintf_appenddouble(char **buffer, int *pos, case 'f': case 'F': #ifdef HAVE_LOCALE_H +#ifdef ZTS + localeconv_r(&lconv); +#else lconv = localeconv(); #endif +#endif s = php_conv_fp((fmt == 'f')?'F':fmt, number, 0, precision, (fmt == 'f')?LCONV_DECIMAL_POINT:'.', &is_negative, &num_buf[1], &s_len); @@ -270,8 +282,12 @@ php_sprintf_appenddouble(char **buffer, int *pos, * * We use &num_buf[ 1 ], so that we have room for the sign */ #ifdef HAVE_LOCALE_H +#ifdef ZTS + localeconv_r(&lconv); +#else lconv = localeconv(); #endif +#endif s = php_gcvt(number, precision, LCONV_DECIMAL_POINT, (fmt == 'G')?'E':'e', &num_buf[1]); is_negative = 0; if (*s == '-') { diff --git a/ext/standard/tests/strings/bug65230.phpt b/ext/standard/tests/strings/bug65230.phpt new file mode 100644 index 0000000000..ca2c3ca922 --- /dev/null +++ b/ext/standard/tests/strings/bug65230.phpt @@ -0,0 +1,60 @@ +--TEST-- +Bug #65230 setting locale randomly broken +--SKIPIF-- +<?php +if (substr(PHP_OS, 0, 3) != 'WIN') { + die('skip'); +} +?> +--INI-- +date.timezone=Europe/Berlin +--FILE-- +<?php + +function test($locale, $value) +{ + $newlocale = setlocale(LC_ALL, $locale); + $conv = localeconv(); + $sep = $conv['decimal_point']; + + printf("%s\n--------------------------\n", $newlocale); + printf(" sep: %s\n", $sep); + printf(" %%f: %f\n", $value); + printf(" %%F: %F\n", $value); + printf("date: %s\n", strftime('%x')); + printf("\n"); +} + +test('german', 3.41); +test('english', 3.41); +test('french', 3.41); +test('german', 3.41); +--EXPECT-- +German_Germany.1252 +-------------------------- + sep: , + %f: 3,410000 + %F: 3.410000 +date: 05.12.2014 + +English_United States.1252 +-------------------------- + sep: . + %f: 3.410000 + %F: 3.410000 +date: 12/5/2014 + +French_France.1252 +-------------------------- + sep: , + %f: 3,410000 + %F: 3.410000 +date: 05/12/2014 + +German_Germany.1252 +-------------------------- + sep: , + %f: 3,410000 + %F: 3.410000 +date: 05.12.2014 + diff --git a/main/snprintf.c b/main/snprintf.c index 1c73dcdcb7..64b6633655 100644 --- a/main/snprintf.c +++ b/main/snprintf.c @@ -38,7 +38,11 @@ #ifdef HAVE_LOCALE_H #include <locale.h> +#ifdef ZTS +#define LCONV_DECIMAL_POINT (*lconv.decimal_point) +#else #define LCONV_DECIMAL_POINT (*lconv->decimal_point) +#endif #else #define LCONV_DECIMAL_POINT '.' #endif @@ -606,8 +610,12 @@ static int format_converter(register buffy * odp, const char *fmt, va_list ap) / char char_buf[2]; /* for printing %% and %<unknown> */ #ifdef HAVE_LOCALE_H +#ifdef ZTS + struct lconv lconv; +#else struct lconv *lconv = NULL; #endif +#endif /* * Flag variables @@ -998,10 +1006,14 @@ static int format_converter(register buffy * odp, const char *fmt, va_list ap) / s_len = 3; } else { #ifdef HAVE_LOCALE_H +#ifdef ZTS + localeconv_r(&lconv); +#else if (!lconv) { lconv = localeconv(); } #endif +#endif s = php_conv_fp((*fmt == 'f')?'F':*fmt, fp_num, alternate_form, (adjust_precision == NO) ? FLOAT_DIGITS : precision, (*fmt == 'f')?LCONV_DECIMAL_POINT:'.', @@ -1055,10 +1067,14 @@ static int format_converter(register buffy * odp, const char *fmt, va_list ap) / * * We use &num_buf[ 1 ], so that we have room for the sign */ #ifdef HAVE_LOCALE_H +#ifdef ZTS + localeconv_r(&lconv); +#else if (!lconv) { lconv = localeconv(); } #endif +#endif s = php_gcvt(fp_num, precision, (*fmt=='H' || *fmt == 'k') ? '.' : LCONV_DECIMAL_POINT, (*fmt == 'G' || *fmt == 'H')?'E':'e', &num_buf[1]); if (*s == '-') { prefix_char = *s++; diff --git a/main/spprintf.c b/main/spprintf.c index 5b16d51441..212914fe9d 100644 --- a/main/spprintf.c +++ b/main/spprintf.c @@ -93,7 +93,11 @@ #ifdef HAVE_LOCALE_H #include <locale.h> +#ifdef ZTS +#define LCONV_DECIMAL_POINT (*lconv.decimal_point) +#else #define LCONV_DECIMAL_POINT (*lconv->decimal_point) +#endif #else #define LCONV_DECIMAL_POINT '.' #endif @@ -217,8 +221,12 @@ static void xbuf_format_converter(smart_str *xbuf, const char *fmt, va_list ap) char char_buf[2]; /* for printing %% and %<unknown> */ #ifdef HAVE_LOCALE_H +#ifdef ZTS + struct lconv lconv; +#else struct lconv *lconv = NULL; #endif +#endif /* * Flag variables @@ -608,10 +616,14 @@ static void xbuf_format_converter(smart_str *xbuf, const char *fmt, va_list ap) s_len = 3; } else { #ifdef HAVE_LOCALE_H +#ifdef ZTS + localeconv_r(&lconv); +#else if (!lconv) { lconv = localeconv(); } #endif +#endif s = php_conv_fp((*fmt == 'f')?'F':*fmt, fp_num, alternate_form, (adjust_precision == NO) ? FLOAT_DIGITS : precision, (*fmt == 'f')?LCONV_DECIMAL_POINT:'.', @@ -664,10 +676,14 @@ static void xbuf_format_converter(smart_str *xbuf, const char *fmt, va_list ap) * * We use &num_buf[ 1 ], so that we have room for the sign */ #ifdef HAVE_LOCALE_H +#ifdef ZTS + localeconv_r(&lconv); +#else if (!lconv) { lconv = localeconv(); } #endif +#endif s = php_gcvt(fp_num, precision, (*fmt=='H' || *fmt == 'k') ? '.' : LCONV_DECIMAL_POINT, (*fmt == 'G' || *fmt == 'H')?'E':'e', &num_buf[1]); if (*s == '-') prefix_char = *s++; diff --git a/tests/lang/034.phpt b/tests/lang/034.phpt index cea0797d69..5d2c610926 100644 --- a/tests/lang/034.phpt +++ b/tests/lang/034.phpt @@ -4,10 +4,6 @@ Bug #12647 (Locale settings affecting float parsing) precision=14 --SKIPIF-- <?php # try to activate a german locale -if (substr(PHP_OS, 0, 3) == 'WIN') { - /* skip on windows until #63688 was fixed */ - die('skip'); -} if (setlocale(LC_NUMERIC, "de_DE.UTF-8", "de_DE", "de", "german", "ge", "de_DE.ISO-8859-1") === FALSE) { print "skip Can't find german locale"; } diff --git a/tests/lang/bug30638.phpt b/tests/lang/bug30638.phpt index 945a228eda..30b70f30fb 100644 --- a/tests/lang/bug30638.phpt +++ b/tests/lang/bug30638.phpt @@ -2,10 +2,6 @@ Bug #30638 (localeconv returns wrong LC_NUMERIC settings) (ok to fail on MacOS X) --SKIPIF-- <?php # try to activate a german locale -if (substr(PHP_OS, 0, 3) == 'WIN') { - /* skip on windows until #63688 was fixed */ - die('skip'); -} if (setlocale(LC_NUMERIC, "de_DE.UTF-8", "de_DE", "de", "german", "ge", "de_DE.ISO-8859-1") === FALSE) { print "skip setlocale() failed"; } elseif (strtolower(php_uname('s')) == 'darwin') { |