Skip to content

Commit 44bc38f

Browse files
committed
Issue open-source-parsers#633: Fix issue with maxInt
This patch is a minor fix to Json::OurReader to properly check against maxLargestInt, not maxInt. Some cleanup in the decodeNumber method is included.
1 parent ddc9e0f commit 44bc38f

File tree

1 file changed

+21
-11
lines changed

1 file changed

+21
-11
lines changed

src/lib_json/json_reader.cpp

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1547,36 +1547,46 @@ bool OurReader::decodeNumber(Token& token, Value& decoded) {
15471547
bool isNegative = *current == '-';
15481548
if (isNegative)
15491549
++current;
1550-
// TODO: Help the compiler do the div and mod at compile time or get rid of
1551-
// them.
1552-
Value::LargestUInt maxIntegerValue =
1553-
isNegative ? Value::LargestUInt(Value::minLargestInt)
1554-
: Value::maxLargestUInt;
1555-
Value::LargestUInt threshold = maxIntegerValue / 10;
1550+
1551+
// TODO(issue #960): Change to constexpr
1552+
static const auto positive_threshold = Value::maxLargestUInt / 10;
1553+
static const auto positive_last_digit = Value::maxLargestUInt % 10;
1554+
static const auto negative_threshold =
1555+
Value::LargestUInt(Value::minLargestInt) / 10;
1556+
static const auto negative_last_digit =
1557+
Value::LargestUInt(Value::minLargestInt) % 10;
1558+
1559+
const auto threshold = isNegative ? negative_threshold : positive_threshold;
1560+
const auto last_digit =
1561+
isNegative ? negative_last_digit : positive_last_digit;
1562+
15561563
Value::LargestUInt value = 0;
15571564
while (current < token.end_) {
15581565
Char c = *current++;
15591566
if (c < '0' || c > '9')
15601567
return decodeDouble(token, decoded);
1561-
auto digit(static_cast<Value::UInt>(c - '0'));
1568+
1569+
const auto digit(static_cast<Value::UInt>(c - '0'));
15621570
if (value >= threshold) {
15631571
// We've hit or exceeded the max value divided by 10 (rounded down). If
1564-
// a) we've only just touched the limit, b) this is the last digit, and
1572+
// a) we've only just touched the limit, meaing value == threshold,
1573+
// b) this is the last digit, or
15651574
// c) it's small enough to fit in that rounding delta, we're okay.
15661575
// Otherwise treat this number as a double to avoid overflow.
1567-
if (value > threshold || current != token.end_ ||
1568-
digit > maxIntegerValue % 10) {
1576+
if (value > threshold || current != token.end_ || digit > last_digit) {
15691577
return decodeDouble(token, decoded);
15701578
}
15711579
}
15721580
value = value * 10 + digit;
15731581
}
1582+
15741583
if (isNegative)
15751584
decoded = -Value::LargestInt(value);
1576-
else if (value <= Value::LargestUInt(Value::maxInt))
1585+
else if (value <= Value::LargestUInt(Value::maxLargestInt))
15771586
decoded = Value::LargestInt(value);
15781587
else
15791588
decoded = value;
1589+
15801590
return true;
15811591
}
15821592

0 commit comments

Comments
 (0)