From 808d362b884847567233e95afb33315d9ec81a72 Mon Sep 17 00:00:00 2001 From: Milo Yip Date: Wed, 30 Jul 2014 23:27:17 +0800 Subject: [PATCH 1/2] Fix parsing numbers which are less than 1e-308 Overflow should check sign of exponent. --- include/rapidjson/reader.h | 2 +- test/unittest/readertest.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/include/rapidjson/reader.h b/include/rapidjson/reader.h index 5d3493a..9fd46b1 100644 --- a/include/rapidjson/reader.h +++ b/include/rapidjson/reader.h @@ -796,7 +796,7 @@ private: exp = s.Take() - '0'; while (s.Peek() >= '0' && s.Peek() <= '9') { exp = exp * 10 + (s.Take() - '0'); - if (exp > 308) + if (exp > 308 && !expMinus) // exp > 308 should be rare, so it should be checked first. RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, s.Tell()); } } diff --git a/test/unittest/readertest.cpp b/test/unittest/readertest.cpp index 1b71db8..a933981 100644 --- a/test/unittest/readertest.cpp +++ b/test/unittest/readertest.cpp @@ -137,6 +137,7 @@ TEST(Reader, ParseNumberHandler) { TEST_DOUBLE("2.22507e-308", 2.22507e-308); TEST_DOUBLE("-1.79769e+308", -1.79769e+308); TEST_DOUBLE("-2.22507e-308", -2.22507e-308); + TEST_DOUBLE("4.9406564584124654e-324", 4.9406564584124654e-324); // minimum denormal TEST_DOUBLE("18446744073709551616", 18446744073709551616.0); // 2^64 (max of uint64_t + 1, force to use double) TEST_DOUBLE("-9223372036854775809", -9223372036854775809.0); // -2^63 - 1(min of int64_t + 1, force to use double) From 54566062329fc273a8dc3239c5168d65ede69437 Mon Sep 17 00:00:00 2001 From: Milo Yip Date: Thu, 31 Jul 2014 00:02:02 +0800 Subject: [PATCH 2/2] Add a "must underflow" case as suggested by @pah --- test/unittest/readertest.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/test/unittest/readertest.cpp b/test/unittest/readertest.cpp index a933981..afe0cd7 100644 --- a/test/unittest/readertest.cpp +++ b/test/unittest/readertest.cpp @@ -138,6 +138,7 @@ TEST(Reader, ParseNumberHandler) { TEST_DOUBLE("-1.79769e+308", -1.79769e+308); TEST_DOUBLE("-2.22507e-308", -2.22507e-308); TEST_DOUBLE("4.9406564584124654e-324", 4.9406564584124654e-324); // minimum denormal + TEST_DOUBLE("1e-10000", 0.0); // must underflow TEST_DOUBLE("18446744073709551616", 18446744073709551616.0); // 2^64 (max of uint64_t + 1, force to use double) TEST_DOUBLE("-9223372036854775809", -9223372036854775809.0); // -2^63 - 1(min of int64_t + 1, force to use double)