Commit ad1d22eb authored by Milo Yip's avatar Milo Yip

Fix #509 by checking Nan/Inf when writing a double

parent 44f81f09
...@@ -40,6 +40,7 @@ public: ...@@ -40,6 +40,7 @@ public:
bool IsNan() const { return (u_ & kExponentMask) == kExponentMask && Significand() != 0; } bool IsNan() const { return (u_ & kExponentMask) == kExponentMask && Significand() != 0; }
bool IsInf() const { return (u_ & kExponentMask) == kExponentMask && Significand() == 0; } bool IsInf() const { return (u_ & kExponentMask) == kExponentMask && Significand() == 0; }
bool IsNanOrInf() const { return (u_ & kExponentMask) == kExponentMask; }
bool IsNormal() const { return (u_ & kExponentMask) != 0 || Significand() == 0; } bool IsNormal() const { return (u_ & kExponentMask) != 0 || Significand() == 0; }
bool IsZero() const { return (u_ & (kExponentMask | kSignificandMask)) == 0; } bool IsZero() const { return (u_ & (kExponentMask | kSignificandMask)) == 0; }
......
...@@ -235,6 +235,9 @@ protected: ...@@ -235,6 +235,9 @@ protected:
} }
bool WriteDouble(double d) { bool WriteDouble(double d) {
if (internal::Double(d).IsNanOrInf())
return false;
char buffer[25]; char buffer[25];
char* end = internal::dtoa(d, buffer); char* end = internal::dtoa(d, buffer);
for (char* p = buffer; p != end; ++p) for (char* p = buffer; p != end; ++p)
...@@ -381,6 +384,9 @@ inline bool Writer<StringBuffer>::WriteUint64(uint64_t u) { ...@@ -381,6 +384,9 @@ inline bool Writer<StringBuffer>::WriteUint64(uint64_t u) {
template<> template<>
inline bool Writer<StringBuffer>::WriteDouble(double d) { inline bool Writer<StringBuffer>::WriteDouble(double d) {
if (internal::Double(d).IsNanOrInf())
return false;
char *buffer = os_->Push(25); char *buffer = os_->Push(25);
char* end = internal::dtoa(d, buffer); char* end = internal::dtoa(d, buffer);
os_->Pop(static_cast<size_t>(25 - (end - buffer))); os_->Pop(static_cast<size_t>(25 - (end - buffer)));
......
...@@ -375,3 +375,27 @@ TEST(Writer, InvalidEventSequence) { ...@@ -375,3 +375,27 @@ TEST(Writer, InvalidEventSequence) {
EXPECT_FALSE(writer.IsComplete()); EXPECT_FALSE(writer.IsComplete());
} }
} }
double zero = 0.0; // Use global variable to prevent compiler warning
TEST(Writer, NaN) {
double nan = zero / zero;
EXPECT_TRUE(internal::Double(nan).IsNan());
StringBuffer buffer;
Writer<StringBuffer> writer(buffer);
EXPECT_FALSE(writer.Double(nan));
}
TEST(Writer, Inf) {
double inf = 1.0 / zero;
EXPECT_TRUE(internal::Double(inf).IsInf());
StringBuffer buffer;
{
Writer<StringBuffer> writer(buffer);
EXPECT_FALSE(writer.Double(inf));
}
{
Writer<StringBuffer> writer(buffer);
EXPECT_FALSE(writer.Double(-inf));
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment