From ae9ffb544303f42e14c21224b9d37c3b870a7097 Mon Sep 17 00:00:00 2001 From: Aaron Jacobs Date: Tue, 24 May 2011 03:59:24 +0000 Subject: [PATCH] Fixed a parsing bug in decodeNumber, updating the failing test cases to be correct in the process. (The test cases incorrectly used exact integers instead of scientific notation.) --- src/lib_json/json_reader.cpp | 13 +++++++------ test/data/test_real_09.expected | 2 +- test/data/test_real_11.expected | 2 +- test/data/test_real_12.expected | 1 + test/data/test_real_12.json | 2 ++ 5 files changed, 12 insertions(+), 8 deletions(-) create mode 100644 test/data/test_real_12.expected create mode 100644 test/data/test_real_12.json diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 603fd76..238a3c5 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -573,8 +573,6 @@ Reader::decodeNumber( Token &token ) Value::LargestUInt maxIntegerValue = isNegative ? Value::LargestUInt(-Value::minLargestInt) : Value::maxLargestUInt; Value::LargestUInt threshold = maxIntegerValue / 10; - Value::UInt lastDigitThreshold = Value::UInt( maxIntegerValue % 10 ); - assert( lastDigitThreshold >=0 && lastDigitThreshold <= 9 ); Value::LargestUInt value = 0; while ( current < token.end_ ) { @@ -584,10 +582,13 @@ Reader::decodeNumber( Token &token ) Value::UInt digit(c - '0'); if ( value >= threshold ) { - // If the current digit is not the last one, or if it is - // greater than the last digit of the maximum integer value, - // the parse the number as a double. - if ( current != token.end_ || digit > lastDigitThreshold ) + // We've hit or exceeded the max value divided by 10 (rounded down). If + // a) we've only just touched the limit, b) this is the last digit, and + // c) it's small enough to fit in that rounding delta, we're okay. + // Otherwise treat this number as a double to avoid overflow. + if (value > threshold || + current != token.end_ || + digit > maxIntegerValue % 10) { return decodeDouble( token ); } diff --git a/test/data/test_real_09.expected b/test/data/test_real_09.expected index ee2e5ef..6da815e 100644 --- a/test/data/test_real_09.expected +++ b/test/data/test_real_09.expected @@ -1 +1 @@ -.=19000000000000000001 +.=1.9e+19 diff --git a/test/data/test_real_11.expected b/test/data/test_real_11.expected index 83d3cc3..17f4187 100644 --- a/test/data/test_real_11.expected +++ b/test/data/test_real_11.expected @@ -1 +1 @@ -.=-9300000000000000001 +.=-9.3e+18 diff --git a/test/data/test_real_12.expected b/test/data/test_real_12.expected new file mode 100644 index 0000000..a000319 --- /dev/null +++ b/test/data/test_real_12.expected @@ -0,0 +1 @@ +.=1.844674407370955e+19 diff --git a/test/data/test_real_12.json b/test/data/test_real_12.json new file mode 100644 index 0000000..0a13eed --- /dev/null +++ b/test/data/test_real_12.json @@ -0,0 +1,2 @@ +// 2^64 -> switch to double. +18446744073709551616