float parsing must be locale independent
authorRemi Collet <fedora@famillecollet.com>
Tue, 27 Nov 2012 10:06:49 +0000 (11:06 +0100)
committerRemi Collet <fedora@famillecollet.com>
Tue, 27 Nov 2012 10:06:49 +0000 (11:06 +0100)
configure.in
json_tokener.c
json_util.c
json_util.h

index 387b422..ea3ed67 100644 (file)
@@ -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])
index f5fa8d6..85c530b 100644 (file)
@@ -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;
index 79ae5c7..c144059 100644 (file)
 # include <unistd.h>
 #endif /* HAVE_UNISTD_H */
 
+#ifdef HAVE_LOCALE_H
+#include <locale.h>
+#endif /* HAVE_LOCALE_H */
+
 #ifdef WIN32
 # define WIN32_LEAN_AND_MEAN
 # include <windows.h>
@@ -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;
index 277c3a7..b9a69c8 100644 (file)
@@ -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);
 
 
 /**