diff options
author | Jo-Philipp Wich <jo@mein.io> | 2023-10-09 15:21:05 +0200 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2023-10-09 15:35:16 +0200 |
commit | 7c209d736907e18ec8d79a57328c1e3bad7b2786 (patch) | |
tree | aaf07f36605e17d8a23f7e09806716cce90ff146 /types.c | |
parent | 9f9959cb23bbec0c57e12029c2b6d10dd53b28dc (diff) |
types: ensure double serializatiion with decimal places
The `%g` printf format used for serializing double values into strings
will not include any decimal place if the value happens to be integral,
leading to an unwanted double to integer conversion when serializing
and subsequently deserializing an integral double value as JSON.
Solve this issue by checking the serialized string result for a decimal
point or exponential notation and appending `.0` if neither is found.
Ref: #173
Suggested-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Diffstat (limited to 'types.c')
-rw-r--r-- | types.c | 17 |
1 files changed, 16 insertions, 1 deletions
@@ -1561,6 +1561,21 @@ ucv_to_stringbuf_add_padding(uc_stringbuf_t *pb, char pad_char, size_t pad_size) } } +static void +ucv_to_stringbuf_add_double(uc_stringbuf_t *pb, double val, bool json) +{ + int len = ucv_stringbuf_printf(pb, "%.14g", val); + + if (!json) + return; + + for (char *p = pb->buf + pb->bpos - len; len > 0; len--, p++) + if (*p == '.' || *p == 'e') + return; + + ucv_stringbuf_append(pb, ".0"); +} + void ucv_to_stringbuf_formatted(uc_vm_t *vm, uc_stringbuf_t *pb, uc_value_t *uv, size_t depth, char pad_char, size_t pad_size) { @@ -1624,7 +1639,7 @@ ucv_to_stringbuf_formatted(uc_vm_t *vm, uc_stringbuf_t *pb, uc_value_t *uv, size else if (d == -INFINITY) ucv_stringbuf_append(pb, "-Infinity"); else - ucv_stringbuf_printf(pb, "%.14g", d); + ucv_to_stringbuf_add_double(pb, d, json); break; |