(trunk libT) #2046: fix JSON bug when parsing floating point numbers in some locales
This commit is contained in:
parent
a0e34bc270
commit
7f08a87969
|
@ -54,6 +54,7 @@ SOFTWARE.
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
|
#include <locale.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -476,7 +477,13 @@ static int parse_parse_buffer(JSON_parser jc)
|
||||||
value.vu.str.value = jc->parse_buffer;
|
value.vu.str.value = jc->parse_buffer;
|
||||||
value.vu.str.length = jc->parse_buffer_count;
|
value.vu.str.length = jc->parse_buffer_count;
|
||||||
} else {
|
} else {
|
||||||
|
/* the json spec requires a '.' decimal point regardless of locale */
|
||||||
|
char numeric[128];
|
||||||
|
snprintf(numeric, sizeof(numeric), "%s", setlocale(LC_NUMERIC, NULL));
|
||||||
|
setlocale(LC_NUMERIC, "POSIX" );
|
||||||
sscanf(jc->parse_buffer, "%Lf", &value.vu.float_value);
|
sscanf(jc->parse_buffer, "%Lf", &value.vu.float_value);
|
||||||
|
value.vu.float_value = strtod(jc->parse_buffer, NULL);
|
||||||
|
setlocale(LC_NUMERIC, numeric);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case JSON_T_INTEGER:
|
case JSON_T_INTEGER:
|
||||||
|
|
|
@ -479,15 +479,14 @@ tr_bencGetReal( const tr_benc * val, double * setme )
|
||||||
if( !success && tr_bencIsString(val) )
|
if( !success && tr_bencIsString(val) )
|
||||||
{
|
{
|
||||||
char * endptr;
|
char * endptr;
|
||||||
char * locale;
|
char locale[128];
|
||||||
double d;
|
double d;
|
||||||
|
|
||||||
/* the json spec requires a '.' decimal point regardless of locale */
|
/* the json spec requires a '.' decimal point regardless of locale */
|
||||||
locale = tr_strdup( setlocale ( LC_NUMERIC, NULL ) );
|
tr_strlcpy( locale, setlocale( LC_NUMERIC, NULL ), sizeof( locale ) );
|
||||||
setlocale( LC_NUMERIC, "POSIX" );
|
setlocale( LC_NUMERIC, "POSIX" );
|
||||||
d = strtod( val->val.s.s, &endptr );
|
d = strtod( val->val.s.s, &endptr );
|
||||||
setlocale( LC_NUMERIC, locale );
|
setlocale( LC_NUMERIC, locale );
|
||||||
tr_free( locale );
|
|
||||||
|
|
||||||
if(( success = ( val->val.s.s != endptr ) && !*endptr ))
|
if(( success = ( val->val.s.s != endptr ) && !*endptr ))
|
||||||
*setme = d;
|
*setme = d;
|
||||||
|
@ -1062,15 +1061,14 @@ static void
|
||||||
saveRealFunc( const tr_benc * val, void * evbuf )
|
saveRealFunc( const tr_benc * val, void * evbuf )
|
||||||
{
|
{
|
||||||
char buf[128];
|
char buf[128];
|
||||||
char * locale;
|
char locale[128];
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
/* always use a '.' decimal point s.t. locale-hopping doesn't bite us */
|
/* always use a '.' decimal point s.t. locale-hopping doesn't bite us */
|
||||||
locale = tr_strdup( setlocale ( LC_NUMERIC, NULL ) );
|
tr_strlcpy( locale, setlocale( LC_NUMERIC, NULL ), sizeof( locale ) );
|
||||||
setlocale( LC_NUMERIC, "POSIX" );
|
setlocale( LC_NUMERIC, "POSIX" );
|
||||||
tr_snprintf( buf, sizeof( buf ), "%f", val->val.d );
|
tr_snprintf( buf, sizeof( buf ), "%f", val->val.d );
|
||||||
setlocale( LC_NUMERIC, locale );
|
setlocale( LC_NUMERIC, locale );
|
||||||
tr_free( locale );
|
|
||||||
|
|
||||||
len = strlen( buf );
|
len = strlen( buf );
|
||||||
evbuffer_add_printf( evbuf, "%lu:", (unsigned long)len );
|
evbuffer_add_printf( evbuf, "%lu:", (unsigned long)len );
|
||||||
|
@ -1278,14 +1276,13 @@ static void
|
||||||
jsonRealFunc( const tr_benc * val, void * vdata )
|
jsonRealFunc( const tr_benc * val, void * vdata )
|
||||||
{
|
{
|
||||||
struct jsonWalk * data = vdata;
|
struct jsonWalk * data = vdata;
|
||||||
char * locale;
|
char locale[128];
|
||||||
|
|
||||||
/* json requires a '.' decimal point regardless of locale */
|
/* json requires a '.' decimal point regardless of locale */
|
||||||
locale = tr_strdup( setlocale ( LC_NUMERIC, NULL ) );
|
tr_strlcpy( locale, setlocale( LC_NUMERIC, NULL ), sizeof( locale ) );
|
||||||
setlocale( LC_NUMERIC, "POSIX" );
|
setlocale( LC_NUMERIC, "POSIX" );
|
||||||
evbuffer_add_printf( data->out, "%f", val->val.d );
|
evbuffer_add_printf( data->out, "%f", val->val.d );
|
||||||
setlocale( LC_NUMERIC, locale );
|
setlocale( LC_NUMERIC, locale );
|
||||||
tr_free( locale );
|
|
||||||
|
|
||||||
jsonChildFunc( data );
|
jsonChildFunc( data );
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue