From e8ba2a1899e70f1ae0507b51f8a3189fbf7cd618 Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Thu, 27 May 2021 16:58:47 -0700 Subject: [PATCH] Added a fix for locales that output ',' as decimal separator. --- tests/bindings/lua/test_upb.lua | 11 +++++++++++ upb/json_encode.c | 10 ++++++++++ 2 files changed, 21 insertions(+) diff --git a/tests/bindings/lua/test_upb.lua b/tests/bindings/lua/test_upb.lua index f58c152a46..98468970e8 100644 --- a/tests/bindings/lua/test_upb.lua +++ b/tests/bindings/lua/test_upb.lua @@ -747,6 +747,17 @@ function test_json_emit_defaults() local json = upb.json_encode(msg, {upb.JSONENC_EMITDEFAULTS}) end +function test_json_locale() + local msg = test_messages_proto3.TestAllTypesProto3() + msg.optional_double = 1.1 + local original_locale = os.setlocale(nil) + os.setlocale("C") + local json = upb.json_encode(msg) + os.setlocale("de_DE.utf8") + assert_equal(json, upb.json_encode(msg)) + os.setlocale(original_locale) -- Restore. +end + function test_encode_depth_limit() local msg = test_messages_proto3.TestAllTypesProto3() msg.recursive_message = msg diff --git a/upb/json_encode.c b/upb/json_encode.c index bc31baf181..31725cfdd1 100644 --- a/upb/json_encode.c +++ b/upb/json_encode.c @@ -307,7 +307,17 @@ static void jsonenc_double(jsonenc *e, const char *fmt, double val) { } else if (val != val) { jsonenc_putstr(e, "\"NaN\""); } else { + char *p = e->ptr; jsonenc_printf(e, fmt, val); + + /* printf() is dependent on locales; sadly there is no easy and portable way + * to avoid this. This little post-processing step will translate 1,2 -> 1.2 + * since JSON needs the latter. Arguably a hack, but it is simple and the + * alternatives are far more complicated, platform-dependent, and/or larger + * in code size. */ + for (char *end = e->ptr; p < end; p++) { + if (*p == ',') *p = '.'; + } } }