Bug 7021 - locale (faulty?) interfacts with strtod()
Summary: locale (faulty?) interfacts with strtod()
Status: RESOLVED INVALID
Alias: None
Product: glibc
Classification: Unclassified
Component: libc (show other bugs)
Version: 2.8
: P2 normal
Target Milestone: ---
Assignee: Ulrich Drepper
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-11-11 14:49 UTC by Frederic Marmond
Modified: 2014-07-01 21:14 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:
fweimer: security-


Attachments
testcase that shows the problem (472 bytes, text/x-csrc)
2008-11-11 14:50 UTC, Frederic Marmond
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Frederic Marmond 2008-11-11 14:49:44 UTC
When using strtod() for converting a string to float, the behavior of strtod is
affected by current locale settings and may fail converting simple value as "1.1".

For example, in French locale, the decimal delimiter is comma ',', and not '.'
It may not be a bug, but a feature, ok, on a certain point of view.
 
But please consider now that this function is used to decode a string that comes
from a config file (and so, technical, written in english), value will be "1.1"
for example. 
It will work as long as the locale is 'english friendly', but this config value
will fail decoding (the "dot 1" will be forgotten) when using an other locale,
let's say french one. => technical layer of a software may fail because
functional part uses certain locale. And what about 3rd parties libraries? They
may be affected by the main application locale policy...


You'll understand better with this little testcase:

/* litle testcase that shows potentially problematic use of stdlib when using locale
* Here, it's not really a problem, as we know when we use french localization...
* But imagine you use user's one? (using: setlocale(LC_ALL,""); )
* And what it you write a 3rd party library, that don't know how the main() prog
will handle localization?!?
* That may be really dangerous!!!
*/
#include "stdlib.h"
#include "stdio.h"
#include "locale.h"
int main(int argc,char** argv)
{
    /*default locale is "C", that is equivalent to: setlocale(LC_ALL,"C");*/
    const char* value="12.34";
    printf("Will decode this string value :%s\n",value);
    printf("Locale is default: decoded value=%f\n",strtod(value,NULL));
    setlocale(LC_ALL,"fr_FR.UTF-8");
    printf("Locale is french: decoded value=%f\n",strtod(value,NULL));
    printf("Funny, isn't it?!?\n");
    return 0;
}

  
Here is the runtime:
[fred@will /tmp]% gcc strtod_locale.c -o strtod_locale && ./strtod_locale
Will decode this string value :12.34
Locale is default: decoded value=12.340000
Locale is french: decoded value=12,000000
Funny, isn't it?!?


My suggestion is to make strtod interpret all locales decimal separators (I know
dot and comma, I don't know if some other locales uses other symbols).

Maybe this url may help understand the problem:
http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/stdlib/Attic/strtod.c.diff?r1=1.10&r2=1.11&f=h

For a detailed history of the bug, you may refer here:
http://fmarmond.blogspot.com/2008/11/stdlib-and-locale-problems-for-3rd.html

Feel free to contact me!
Comment 1 Frederic Marmond 2008-11-11 14:50:48 UTC
Created attachment 3055 [details]
testcase that shows the problem
Comment 2 Ulrich Drepper 2008-11-11 14:59:11 UTC
This is not a bug, it's the expected behavior.  If you need to parse strings
using the information from the C locale, switch to that locale temporarily or
use strtod_l with an appropriate locale parameter.
Comment 3 Frederic Marmond 2008-11-11 15:14:48 UTC
(In reply to comment #2)
> This is not a bug, it's the expected behavior.  If you need to parse strings
> using the information from the C locale, switch to that locale temporarily or
> use strtod_l with an appropriate locale parameter.

switching locale for each call wouldn't be an option in many cases, but I think
strtod_l is the right answer! 
I wasn't aware of this function (it even doesn't appear in my installed
man-pages... and I can't find package that may contain docs for it !).
Thanks for pointing it to me!