[libvirt] [PATCH v2] util: fix locale problem with virStrToDouble().

Julio Faracco jcfaracco at gmail.com
Sun Jun 18 18:20:11 UTC 2017


This commit fixes a locale problem with locales that use comma as a mantissa
separator. Example: 12.34 en_US = 12,34 pt_BR. Since strtod() is a non-safe
function, virStrToDouble() will have problems to parse double numbers from
kernel settings and other double numbers from static files (XMLs, JSONs, etc).

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1457634
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1457481

Signed-off-by: Julio Faracco <jcfaracco at gmail.com>
---
 src/util/virstring.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/src/util/virstring.c b/src/util/virstring.c
index 089b539..6dd5138 100644
--- a/src/util/virstring.c
+++ b/src/util/virstring.c
@@ -28,6 +28,7 @@
 #include "base64.h"
 #include "c-ctype.h"
 #include "virstring.h"
+#include "virthread.h"
 #include "viralloc.h"
 #include "virbuffer.h"
 #include "virerror.h"
@@ -516,6 +517,22 @@ virStrToLong_ullp(char const *s, char **end_ptr, int base,
     return 0;
 }
 
+#if HAVE_NEWLOCALE
+
+static locale_t virLocale;
+
+static int
+virLocaleOnceInit(void)
+{
+    virLocale = newlocale(LC_ALL_MASK, "C", (locale_t)0);
+    if (!virLocale)
+        return -1;
+    return 0;
+}
+
+VIR_ONCE_GLOBAL_INIT(virLocale);
+#endif
+
 int
 virStrToDouble(char const *s,
                char **end_ptr,
@@ -526,7 +543,17 @@ virStrToDouble(char const *s,
     int err;
 
     errno = 0;
+#if HAVE_NEWLOCALE
+    locale_t old_loc;
+    if (virLocaleInitialize() < 0)
+        return -1;
+
+    old_loc = uselocale(virLocale);
+#endif
     val = strtod(s, &p); /* exempt from syntax-check */
+#if HAVE_NEWLOCALE
+    uselocale(old_loc);
+#endif
     err = (errno || (!end_ptr && *p) || p == s);
     if (end_ptr)
         *end_ptr = p;
-- 
2.7.4




More information about the libvir-list mailing list