libvirt creates invalid commands if wrong locale is selected. For example with locale that uses comma as a decimal point, JSON commands created with decimal numbers are invalid because comma separates the entries in JSON. But even when decimal point is affected, grouping is not, because for grouping to be enabled with *printf, there has to be a apostrophe flag specified (and supported). --- Fortunately, there should be no other place where output-formatting is affected by this problem. I tried to change this in various ways with this posted one being the cleanest from my point of view, because: - setting locale is per-proccess, not per-thread (not thread-safe) - there is no number parsing that mangles the output number because of floating point precision src/util/json.c | 23 +++++++++++++++++++++-- 1 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/util/json.c b/src/util/json.c index 5132989..753a548 100644 --- a/src/util/json.c +++ b/src/util/json.c @@ -23,6 +23,8 @@ #include <config.h> +#include <locale.h> + #include "json.h" #include "memory.h" #include "virterror_internal.h" @@ -44,7 +46,6 @@ /* XXX fixme */ #define VIR_FROM_THIS VIR_FROM_NONE - typedef struct _virJSONParserState virJSONParserState; typedef virJSONParserState *virJSONParserStatePtr; struct _virJSONParserState { @@ -200,9 +201,27 @@ virJSONValuePtr virJSONValueNewNumberUlong(unsigned long long data) virJSONValuePtr virJSONValueNewNumberDouble(double data) { virJSONValuePtr val = NULL; - char *str; + char *str, *radix, *tmp; + if (virAsprintf(&str, "%lf", data) < 0) return NULL; + + /* because printing double is locale-dependent, we could end up + * with invalid JSON code, so we have to do something like this */ + radix = localeconv()->decimal_point; + tmp = strstr(str, radix); + if (tmp) { + *tmp = '.'; + if (strlen(radix) > 1) { + /* if the current locale specifies more characters as + * decimal point then cover the others with decimal + * numbers */ + memcpy(tmp + 1, + tmp + strlen(radix), + strlen(str) - (tmp - str)); + } + } + val = virJSONValueNewNumber(str); VIR_FREE(str); return val; -- 1.7.8.6 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list