Skip to content

Commit ae9ffb5

Browse files
committed
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.)
1 parent e656c5f commit ae9ffb5

File tree

5 files changed

+12
-8
lines changed

5 files changed

+12
-8
lines changed

src/lib_json/json_reader.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -573,8 +573,6 @@ Reader::decodeNumber( Token &token )
573573
Value::LargestUInt maxIntegerValue = isNegative ? Value::LargestUInt(-Value::minLargestInt)
574574
: Value::maxLargestUInt;
575575
Value::LargestUInt threshold = maxIntegerValue / 10;
576-
Value::UInt lastDigitThreshold = Value::UInt( maxIntegerValue % 10 );
577-
assert( lastDigitThreshold >=0 && lastDigitThreshold <= 9 );
578576
Value::LargestUInt value = 0;
579577
while ( current < token.end_ )
580578
{
@@ -584,10 +582,13 @@ Reader::decodeNumber( Token &token )
584582
Value::UInt digit(c - '0');
585583
if ( value >= threshold )
586584
{
587-
// If the current digit is not the last one, or if it is
588-
// greater than the last digit of the maximum integer value,
589-
// the parse the number as a double.
590-
if ( current != token.end_ || digit > lastDigitThreshold )
585+
// We've hit or exceeded the max value divided by 10 (rounded down). If
586+
// a) we've only just touched the limit, b) this is the last digit, and
587+
// c) it's small enough to fit in that rounding delta, we're okay.
588+
// Otherwise treat this number as a double to avoid overflow.
589+
if (value > threshold ||
590+
current != token.end_ ||
591+
digit > maxIntegerValue % 10)
591592
{
592593
return decodeDouble( token );
593594
}

test/data/test_real_09.expected

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
.=19000000000000000001
1+
.=1.9e+19

test/data/test_real_11.expected

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
.=-9300000000000000001
1+
.=-9.3e+18

test/data/test_real_12.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.=1.844674407370955e+19

test/data/test_real_12.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// 2^64 -> switch to double.
2+
18446744073709551616

0 commit comments

Comments
 (0)