Closed bhaible closed 4 months ago
The cause is that the conversion from double to string, in strconv.c: jsonp_dtostr
, uses the localeconv()
function, which is not multithread-safe (see POSIX https://pubs.opengroup.org/onlinepubs/9699919799/functions/localeconv.html ). In particular, in glibc, localeconv()
returns a pointer to a static
variable.
So, in thread1 with its English locale, localeconv()->decimal_point
is "."
, whereas in thread2 with its French locale, localeconv()->decimal_point
is ","
.
In thread2, the snprintf
call produces "2,5". Then, in the from_locale(buffer)
call, it can happen that the return value of localeconv()
is disturbed by thread1, such that localeconv()->decimal_point
returns "."
. In this case, the function from_locale
does not change the result, and the comma remains in the result.
The fix is to use sprintf (buffer, "%#.0f", 1.0)
instead of localeconv()
. sprintf
is multithread-safe.
Thanks! Fixed in #677.
When two different threads use
json_dumps
to convert a JSON object to a string, they can disturb each other: one of the threads may produce wrong results.How to reproduce: On a system with glibc, compile and run the following program
foo.c
:Like this:
Note: The test program fulfils the rules documented in https://jansson.readthedocs.io/en/latest/threadsafety.html :
json_t
objects are private to each of the threads.setlocale
.