summaryrefslogtreecommitdiffhomepage
path: root/types.c
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2023-10-09 15:21:05 +0200
committerJo-Philipp Wich <jo@mein.io>2023-10-09 15:35:16 +0200
commit7c209d736907e18ec8d79a57328c1e3bad7b2786 (patch)
treeaaf07f36605e17d8a23f7e09806716cce90ff146 /types.c
parent9f9959cb23bbec0c57e12029c2b6d10dd53b28dc (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.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/types.c b/types.c
index c9472f7..eeac8c7 100644
--- a/types.c
+++ b/types.c
@@ -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;