php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #30638 localeconv returns wrong LC_NUMERIC settings
Submitted: 2004-11-01 01:14 UTC Modified: 2004-11-04 00:45 UTC
From: k at ailis dot de Assigned: derick (profile)
Status: Closed Package: *Languages/Translation
PHP Version: 5.0.2 OS: Linux
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: k at ailis dot de
New email:
PHP Version: OS:

 

 [2004-11-01 01:14 UTC] k at ailis dot de
Description:
------------
If locale is switched to a european language (like de_DE) then localeconv returns wrong settings for decimal_point and thousands_sep while other data (like mon_decimal_point and mon_thousands_sep) is correct.

This bug was introduced by this patch for ext/standard/string.c:

$Id: string.c,v 1.320 2002/10/10 16:29:35 iliaa Exp $

This patch modified setlocale() so it resets the LC_NUMERIC locale to C. This was a bad enough but there were reasons I agree to.

Here is a patch which corrects this bug by remembering the LC_NUMERIC locale, setting this remembered locale before calling localeconv_r() and resetting it to C after the call. In that way localeconv() returns the correct data and PHP can still stick to LC_NUMERIC=C:

diff -Nur php-src.orig/ext/standard/basic_functions.c php-src/ext/standard/basic_functions.c
--- php-src.orig/ext/standard/basic_functions.c	2004-10-09 00:19:03.000000000 +0200
+++ php-src/ext/standard/basic_functions.c	2004-11-01 00:36:48.000000000 +0100
@@ -1156,6 +1156,7 @@
 	BG(strtok_string) = NULL;
 	BG(strtok_zval) = NULL;
 	BG(locale_string) = NULL;
+	BG(numeric_locale_string) = NULL;
 	BG(user_compare_func_name) = NULL;
 	BG(array_walk_func_name) = NULL;
 	BG(page_uid) = -1;
@@ -1212,7 +1213,8 @@
 		setlocale(LC_CTYPE, "");
 	}
 	STR_FREE(BG(locale_string));
-
+    STR_FREE(BG(numeric_locale_string));
+    
 	if (FG(stream_wrappers)) {
 		zend_hash_destroy(FG(stream_wrappers));
 		efree(FG(stream_wrappers));
diff -Nur php-src.orig/ext/standard/basic_functions.h php-src/ext/standard/basic_functions.h
--- php-src.orig/ext/standard/basic_functions.h	2004-08-07 17:59:59.000000000 +0200
+++ php-src/ext/standard/basic_functions.h	2004-11-01 00:30:18.000000000 +0100
@@ -155,6 +155,7 @@
 	zval *strtok_zval;
 	char *strtok_string;
 	char *locale_string;
+	char *numeric_locale_string;
 	char *strtok_last;
 	char strtok_table[256];
 	ulong strtok_len;
diff -Nur php-src.orig/ext/standard/string.c php-src/ext/standard/string.c
--- php-src.orig/ext/standard/string.c	2004-10-21 00:44:43.000000000 +0200
+++ php-src/ext/standard/string.c	2004-11-01 00:36:01.000000000 +0100
@@ -3799,6 +3799,10 @@
 			
 				EG(float_separator)[0] = (lc.decimal_point)[0];
 
+                /* Remember numeric locale */
+                STR_FREE(BG(numeric_locale_string));
+                BG(numeric_locale_string) = estrdup(loc);
+                
 				if ((lc.decimal_point)[0] != '.') {
 					/* set locale back to C */
 					setlocale(LC_NUMERIC, "C");	
@@ -4351,7 +4355,18 @@
 	{
 		struct lconv currlocdata;
 
+        /* Remember numeric locale */
+        if (BG(numeric_locale_string)) {
+            setlocale(LC_NUMERIC, BG(numeric_locale_string));
+        }
+
+        /* Fetch formatting information */
 		localeconv_r( &currlocdata );
+		
+		/* Reset numeric locale to C */
+		if (BG(numeric_locale_string)) {
+		    setlocale(LC_NUMERIC, "C");
+		}
    
 		/* Grab the grouping data out of the array */
 		len = strlen(currlocdata.grouping);


Reproduce code:
---------------
<?php

setlocale(LC_ALL, 'de_DE');
$lc = localeconv();
printf("decimal_point: %s\n", $lc['decimal_point']);
printf("thousands_sep: %s\n", $lc['thousands_sep']);

?>


Expected result:
----------------
decimal_point: ,
thousands_sep: .


Actual result:
--------------
decimal_point: .
thousands_sep: 


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2004-11-01 07:51 UTC] derick@php.net
I think this patch is  abit too much magic myself. We should reconsider the setting of LS_NUMERIC to "C" when we call setlocale(). I'll investigate.
 [2004-11-02 00:37 UTC] iliaa@php.net
we call localeconv when we change locale for numeric or all types. If we were cache this data, we could make localeconv return it without any magic.
 [2004-11-04 00:45 UTC] derick@php.net
This bug has been fixed in CVS.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.


 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Nov 22 05:01:29 2024 UTC