From d0fd3bf62ef8d5f6abf13c8206313c57559f1edd Mon Sep 17 00:00:00 2001 From: Derick Rethans Date: Wed, 3 Nov 2004 23:27:28 +0000 Subject: [PATCH] - MFH: Fixed bug #30630: Added a BSD based strtod function that is locale-independent. (PHP part) --- configure.in | 2 +- ext/soap/php_encoding.c | 3 ++- ext/standard/formatted_print.c | 9 ++++++++- ext/standard/php_string.h | 2 +- ext/standard/scanf.c | 3 ++- ext/standard/string.c | 14 +------------- tests/lang/034.phpt | 3 +-- tests/lang/bug30638.phpt | 20 ++++++++++++++++++++ 8 files changed, 36 insertions(+), 20 deletions(-) create mode 100644 tests/lang/bug30638.phpt diff --git a/configure.in b/configure.in index 04fd112796..e008038f81 100644 --- a/configure.in +++ b/configure.in @@ -1248,7 +1248,7 @@ PHP_ADD_SOURCES(Zend, \ zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \ zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \ zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \ - zend_iterators.c zend_interfaces.c zend_exceptions.c) + zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c) if test -r "$abs_srcdir/Zend/zend_objects.c"; then PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_mm.c \ diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c index 5be092d660..14d781e102 100644 --- a/ext/soap/php_encoding.c +++ b/ext/soap/php_encoding.c @@ -23,6 +23,7 @@ #include "php_soap.h" #include "ext/libxml/php_libxml.h" +#include "zend_strtod.h" /* zval type decode */ static zval *to_zval_double(encodeTypePtr type, xmlNodePtr data); @@ -686,7 +687,7 @@ static zval *to_zval_long(encodeTypePtr type, xmlNodePtr data) errno = 0; ret->value.lval = strtol(data->children->content, NULL, 0); if (errno == ERANGE) { /* overflow */ - ret->value.dval = strtod(data->children->content, NULL); + ret->value.dval = zend_strtod(data->children->content, NULL); ret->type = IS_DOUBLE; } else { ret->type = IS_LONG; diff --git a/ext/standard/formatted_print.c b/ext/standard/formatted_print.c index 1e71a937d5..e35946fa10 100644 --- a/ext/standard/formatted_print.c +++ b/ext/standard/formatted_print.c @@ -303,7 +303,14 @@ php_sprintf_appenddouble(char **buffer, int *pos, char *cvt; register int i = 0, j = 0; int sign, decpt, cvt_len; - char decimal_point = EG(float_separator)[0]; +#ifdef HAVE_LOCALE_H + struct lconv lc; + char decimal_point; + localeconv_r(&lc); + decimal_point = (lc.decimal_point)[0]; +#else + char decimal_point = '.'; +#endif PRINTF_DEBUG(("sprintf: appenddouble(%x, %x, %x, %f, %d, '%c', %d, %c)\n", *buffer, pos, size, number, width, padding, alignment, fmt)); diff --git a/ext/standard/php_string.h b/ext/standard/php_string.h index 3097d4f114..9eddc44055 100644 --- a/ext/standard/php_string.h +++ b/ext/standard/php_string.h @@ -112,7 +112,7 @@ PHP_MINIT_FUNCTION(nl_langinfo); PHPAPI int strnatcmp_ex(char const *a, size_t a_len, char const *b, size_t b_len, int fold_case); #ifdef HAVE_LOCALECONV -struct lconv *localeconv_r(struct lconv *out); +PHPAPI struct lconv *localeconv_r(struct lconv *out); #endif PHPAPI char *php_strtoupper(char *s, size_t len); diff --git a/ext/standard/scanf.c b/ext/standard/scanf.c index ba158e598c..8d84d50a9d 100644 --- a/ext/standard/scanf.c +++ b/ext/standard/scanf.c @@ -78,6 +78,7 @@ #endif #include "zend_execute.h" #include "zend_operators.h" +#include "zend_strtod.h" #include "php_globals.h" #include "basic_functions.h" #include "scanf.h" @@ -1204,7 +1205,7 @@ PHPAPI int php_sscanf_internal( char *string, char *format, if (!(flags & SCAN_SUPPRESS)) { double dvalue; *end = '\0'; - dvalue = strtod(buf, NULL); + dvalue = zend_strtod(buf, NULL); if (numVars) { current = args[objIndex++]; convert_to_double( *current ); diff --git a/ext/standard/string.c b/ext/standard/string.c index 79a0eeab0d..2ebaac32d8 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -136,7 +136,7 @@ static char *php_bin2hex(const unsigned char *old, const size_t oldlen, size_t * #ifdef HAVE_LOCALECONV /* {{{ localeconv_r * glibc's localeconv is not reentrant, so lets make it so ... sorta */ -struct lconv *localeconv_r(struct lconv *out) +PHPAPI struct lconv *localeconv_r(struct lconv *out) { struct lconv *res; @@ -3741,18 +3741,6 @@ PHP_FUNCTION(setlocale) efree(args); RETVAL_STRING(retval, 1); - if (cat == LC_NUMERIC || cat == LC_ALL) { - struct lconv lc; - localeconv_r(&lc); - - EG(float_separator)[0] = (lc.decimal_point)[0]; - - if ((lc.decimal_point)[0] != '.') { - /* set locale back to C */ - setlocale(LC_NUMERIC, "C"); - } - } - return; } diff --git a/tests/lang/034.phpt b/tests/lang/034.phpt index 475a0b7568..9c640415d5 100644 --- a/tests/lang/034.phpt +++ b/tests/lang/034.phpt @@ -1,5 +1,5 @@ --TEST-- -Locale settings affecting float parsing +Bug #12647 (Locale settings affecting float parsing) --SKIPIF-- --EXPECT-- 3,14 diff --git a/tests/lang/bug30638.phpt b/tests/lang/bug30638.phpt new file mode 100644 index 0000000000..2574d132d3 --- /dev/null +++ b/tests/lang/bug30638.phpt @@ -0,0 +1,20 @@ +--TEST-- +Bug #30638 (localeconv returns wrong LC_NUMERIC settings) +--SKIPIF-- + +--FILE-- + +--EXPECT-- +decimal_point: , +thousands_sep: . -- 2.40.0