From f6dde18d79488d3dd33c7592a949d311351db6af Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Thu, 16 Nov 2017 18:53:52 +0000 Subject: [PATCH] [Fix] Deal with nan and inf encoding in json/ucl --- contrib/libucl/ucl_emitter_utils.c | 52 ++++++++++++++++++------------ src/libutil/str_util.c | 34 +++++++++++-------- 2 files changed, 51 insertions(+), 35 deletions(-) diff --git a/contrib/libucl/ucl_emitter_utils.c b/contrib/libucl/ucl_emitter_utils.c index 3559eb63d..6c46a8e49 100644 --- a/contrib/libucl/ucl_emitter_utils.c +++ b/contrib/libucl/ucl_emitter_utils.c @@ -207,15 +207,18 @@ ucl_utstring_append_double (double val, void *ud) UT_string *buf = ud; const double delta = 0.0000001; - if (val == (double)(int)val) { - utstring_printf (buf, "%.1lf", val); - } - else if (fabs (val - (double)(int)val) < delta) { - /* Write at maximum precision */ - utstring_printf (buf, "%.*lg", DBL_DIG, val); + if (isfinite (val)) { + if (val == (double) (int) val) { + utstring_printf (buf, "%.1lf", val); + } else if (fabs (val - (double) (int) val) < delta) { + /* Write at maximum precision */ + utstring_printf (buf, "%.*lg", DBL_DIG, val); + } else { + utstring_printf (buf, "%lf", val); + } } else { - utstring_printf (buf, "%lf", val); + utstring_append_len (buf, "null", 5); } return 0; @@ -262,15 +265,19 @@ ucl_file_append_double (double val, void *ud) FILE *fp = ud; const double delta = 0.0000001; - if (val == (double)(int)val) { - fprintf (fp, "%.1lf", val); - } - else if (fabs (val - (double)(int)val) < delta) { - /* Write at maximum precision */ - fprintf (fp, "%.*lg", DBL_DIG, val); + if (isfinite (val)) { + if (val == (double) (int) val) { + fprintf (fp, "%.1lf", val); + } else if (fabs (val - (double) (int) val) < delta) { + /* Write at maximum precision */ + fprintf (fp, "%.*lg", DBL_DIG, val); + } else { + fprintf (fp, "%lf", val); + } } else { - fprintf (fp, "%lf", val); + /* Encode as null */ + fprintf (fp, "null"); } return 0; @@ -336,15 +343,18 @@ ucl_fd_append_double (double val, void *ud) const double delta = 0.0000001; char nbuf[64]; - if (val == (double)(int)val) { - snprintf (nbuf, sizeof (nbuf), "%.1lf", val); - } - else if (fabs (val - (double)(int)val) < delta) { - /* Write at maximum precision */ - snprintf (nbuf, sizeof (nbuf), "%.*lg", DBL_DIG, val); + if (isfinite (val)) { + if (val == (double) (int) val) { + snprintf (nbuf, sizeof (nbuf), "%.1lf", val); + } else if (fabs (val - (double) (int) val) < delta) { + /* Write at maximum precision */ + snprintf (nbuf, sizeof (nbuf), "%.*lg", DBL_DIG, val); + } else { + snprintf (nbuf, sizeof (nbuf), "%lf", val); + } } else { - snprintf (nbuf, sizeof (nbuf), "%lf", val); + memcpy (nbuf, "null", 5); } return write (fd, nbuf, strlen (nbuf)); diff --git a/src/libutil/str_util.c b/src/libutil/str_util.c index 004204881..22d63c302 100644 --- a/src/libutil/str_util.c +++ b/src/libutil/str_util.c @@ -1862,15 +1862,18 @@ rspamd_gstring_append_double (double val, void *ud) GString *buf = ud; const double delta = 0.0000001; - if (val == (double) (int) val) { - rspamd_printf_gstring (buf, "%.1f", val); - } - else if (fabs (val - (double) (int) val) < delta) { - /* Write at maximum precision */ - rspamd_printf_gstring (buf, "%.*g", DBL_DIG, val); + if (isfinite (val)) { + if (val == (double) (int) val) { + rspamd_printf_gstring (buf, "%.1f", val); + } else if (fabs (val - (double) (int) val) < delta) { + /* Write at maximum precision */ + rspamd_printf_gstring (buf, "%.*g", DBL_DIG, val); + } else { + rspamd_printf_gstring (buf, "%f", val); + } } else { - rspamd_printf_gstring (buf, "%f", val); + rspamd_printf_gstring (buf, "null"); } return 0; @@ -1931,15 +1934,18 @@ rspamd_fstring_emit_append_double (double val, void *ud) rspamd_fstring_t **buf = ud; const double delta = 0.0000001; - if (val == (double)((gint) val)) { - rspamd_printf_fstring (buf, "%.1f", val); - } - else if (fabs (val - (double) (int) val) < delta) { - /* Write at maximum precision */ - rspamd_printf_fstring (buf, "%.*g", DBL_DIG, val); + if (isfinite (val)) { + if (val == (double) ((gint) val)) { + rspamd_printf_fstring (buf, "%.1f", val); + } else if (fabs (val - (double) (int) val) < delta) { + /* Write at maximum precision */ + rspamd_printf_fstring (buf, "%.*g", DBL_DIG, val); + } else { + rspamd_printf_fstring (buf, "%f", val); + } } else { - rspamd_printf_fstring (buf, "%f", val); + rspamd_printf_fstring (buf, "null"); } return 0; -- 2.39.5