From: Remi Collet Date: Tue, 27 Nov 2012 10:06:49 +0000 (+0100) Subject: float parsing must be locale independent X-Git-Tag: json-c-0.11-20130402~14^2~4 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=16a4a32e294e80ca8c89ec83e62baa0c59947ac9;p=thirdparty%2Fjson-c.git float parsing must be locale independent --- diff --git a/configure.in b/configure.in index 387b4220..ea3ed67b 100644 --- a/configure.in +++ b/configure.in @@ -23,7 +23,7 @@ AM_CONDITIONAL(ENABLE_OLDNAME_COMPAT, [test "x${enable_oldname_compat}" != "xno" AM_CONFIG_HEADER(config.h) AM_CONFIG_HEADER(json_config.h) AC_HEADER_STDC -AC_CHECK_HEADERS(fcntl.h limits.h strings.h syslog.h unistd.h [sys/cdefs.h] [sys/param.h] stdarg.h) +AC_CHECK_HEADERS(fcntl.h limits.h strings.h syslog.h unistd.h [sys/cdefs.h] [sys/param.h] stdarg.h locale.h) AC_CHECK_HEADER(inttypes.h,[AC_DEFINE([JSON_C_HAVE_INTTYPES_H],[1],[Public define for json_inttypes.h])]) # Checks for typedefs, structures, and compiler characteristics. @@ -35,7 +35,7 @@ AC_FUNC_VPRINTF AC_FUNC_MEMCMP AC_FUNC_MALLOC AC_FUNC_REALLOC -AC_CHECK_FUNCS(strcasecmp strdup strndup strerror snprintf vsnprintf vasprintf open vsyslog strncasecmp) +AC_CHECK_FUNCS(strcasecmp strdup strndup strerror snprintf vsnprintf vasprintf open vsyslog strncasecmp setlocale) #check if .section.gnu.warning accepts long strings (for __warn_references) AC_LANG_PUSH([C]) diff --git a/json_tokener.c b/json_tokener.c index f5fa8d60..85c530b4 100644 --- a/json_tokener.c +++ b/json_tokener.c @@ -585,7 +585,7 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok, double numd; if (!tok->is_double && json_parse_int64(tok->pb->buf, &num64) == 0) { current = json_object_new_int64(num64); - } else if(tok->is_double && sscanf(tok->pb->buf, "%lf", &numd) == 1) { + } else if(tok->is_double && json_parse_double(tok->pb->buf, &numd) == 0) { current = json_object_new_double(numd); } else { tok->err = json_tokener_error_parse_number; diff --git a/json_util.c b/json_util.c index 79ae5c70..c144059f 100644 --- a/json_util.c +++ b/json_util.c @@ -36,6 +36,10 @@ # include #endif /* HAVE_UNISTD_H */ +#ifdef HAVE_LOCALE_H +#include +#endif /* HAVE_LOCALE_H */ + #ifdef WIN32 # define WIN32_LEAN_AND_MEAN # include @@ -142,6 +146,27 @@ int json_object_to_file(char *filename, struct json_object *obj) return json_object_to_file_ext(filename, obj, JSON_C_TO_STRING_PLAIN); } +int json_parse_double(const char *buf, double *retval) +{ + int ret; +#ifdef HAVE_SETLOCALE + char *old=NULL, *tmp; + + tmp = setlocale(LC_NUMERIC, NULL); + if (tmp) old = strdup(tmp); + setlocale(LC_NUMERIC, "C"); +#endif + + ret = sscanf(buf, "%lf", retval); + +#ifdef HAVE_SETLOCALE + setlocale(LC_NUMERIC, old); + if (old) free(old); +#endif + + return (ret==1 ? 0 : 1); +} + int json_parse_int64(const char *buf, int64_t *retval) { int64_t num64; diff --git a/json_util.h b/json_util.h index 277c3a74..b9a69c8b 100644 --- a/json_util.h +++ b/json_util.h @@ -25,6 +25,7 @@ extern struct json_object* json_object_from_file(const char *filename); extern int json_object_to_file(char *filename, struct json_object *obj); extern int json_object_to_file_ext(char *filename, struct json_object *obj, int flags); extern int json_parse_int64(const char *buf, int64_t *retval); +extern int json_parse_double(const char *buf, double *retval); /**