From 2d6d87d10fac26cd1ae928bc5258c8b596d4edd6 Mon Sep 17 00:00:00 2001 From: Julian Brost Date: Tue, 27 Apr 2021 17:24:03 +0200 Subject: [PATCH] Convert::ToString(double): handle integral values too large for long long correctly Even if a double represents an integer value, it might not be safe to cast it to long long as it may overflow the type. Instead just use print the double value with 0 decimals using std::setprecision. Before: <1> => 18446744073709551616.to_string() "-9223372036854775808" After: <1> => 18446744073709551616.to_string() "18446744073709551616" --- lib/base/convert.cpp | 7 ++++--- test/base-convert.cpp | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/base/convert.cpp b/lib/base/convert.cpp index 3c60e1b44..19d3e44e4 100644 --- a/lib/base/convert.cpp +++ b/lib/base/convert.cpp @@ -3,6 +3,7 @@ #include "base/convert.hpp" #include "base/datetime.hpp" #include +#include using namespace icinga; @@ -21,10 +22,10 @@ String Convert::ToString(double val) double integral; double fractional = std::modf(val, &integral); - if (fractional == 0) - return Convert::ToString(static_cast(val)); - std::ostringstream msgbuf; + if (fractional == 0) { + msgbuf << std::setprecision(0); + } msgbuf << std::fixed << val; return msgbuf.str(); } diff --git a/test/base-convert.cpp b/test/base-convert.cpp index 17805ea5c..bc7c61be8 100644 --- a/test/base-convert.cpp +++ b/test/base-convert.cpp @@ -33,12 +33,14 @@ BOOST_AUTO_TEST_CASE(tostring) BOOST_CHECK(Convert::ToString(7) == "7"); BOOST_CHECK(Convert::ToString(7.5) == "7.500000"); BOOST_CHECK(Convert::ToString("hello") == "hello"); + BOOST_CHECK(Convert::ToString(18446744073709551616.0) == "18446744073709551616"); // pow(2, 64) String str = "hello"; BOOST_CHECK(Convert::ToString(str) == "hello"); BOOST_CHECK(Convert::ToString(Value(7)) == "7"); BOOST_CHECK(Convert::ToString(Value(7.5)) == "7.500000"); + BOOST_CHECK(Convert::ToString(Value(18446744073709551616.0)) == "18446744073709551616"); // pow(2, 64) BOOST_CHECK(Convert::ToString(Value("hello")) == "hello"); BOOST_CHECK(Convert::ToString(Value("hello hello")) == "hello hello"); }