mirror of
https://github.com/open-source-parsers/jsoncpp.git
synced 2024-12-27 11:21:02 +08:00
Issue #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.
This commit is contained in:
parent
ddc9e0fcd7
commit
44bc38f0a1
@ -1547,36 +1547,46 @@ bool OurReader::decodeNumber(Token& token, Value& decoded) {
|
|||||||
bool isNegative = *current == '-';
|
bool isNegative = *current == '-';
|
||||||
if (isNegative)
|
if (isNegative)
|
||||||
++current;
|
++current;
|
||||||
// TODO: Help the compiler do the div and mod at compile time or get rid of
|
|
||||||
// them.
|
// TODO(issue #960): Change to constexpr
|
||||||
Value::LargestUInt maxIntegerValue =
|
static const auto positive_threshold = Value::maxLargestUInt / 10;
|
||||||
isNegative ? Value::LargestUInt(Value::minLargestInt)
|
static const auto positive_last_digit = Value::maxLargestUInt % 10;
|
||||||
: Value::maxLargestUInt;
|
static const auto negative_threshold =
|
||||||
Value::LargestUInt threshold = maxIntegerValue / 10;
|
Value::LargestUInt(Value::minLargestInt) / 10;
|
||||||
|
static const auto negative_last_digit =
|
||||||
|
Value::LargestUInt(Value::minLargestInt) % 10;
|
||||||
|
|
||||||
|
const auto threshold = isNegative ? negative_threshold : positive_threshold;
|
||||||
|
const auto last_digit =
|
||||||
|
isNegative ? negative_last_digit : positive_last_digit;
|
||||||
|
|
||||||
Value::LargestUInt value = 0;
|
Value::LargestUInt value = 0;
|
||||||
while (current < token.end_) {
|
while (current < token.end_) {
|
||||||
Char c = *current++;
|
Char c = *current++;
|
||||||
if (c < '0' || c > '9')
|
if (c < '0' || c > '9')
|
||||||
return decodeDouble(token, decoded);
|
return decodeDouble(token, decoded);
|
||||||
auto digit(static_cast<Value::UInt>(c - '0'));
|
|
||||||
|
const auto digit(static_cast<Value::UInt>(c - '0'));
|
||||||
if (value >= threshold) {
|
if (value >= threshold) {
|
||||||
// We've hit or exceeded the max value divided by 10 (rounded down). If
|
// 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
|
// a) we've only just touched the limit, meaing value == threshold,
|
||||||
|
// b) this is the last digit, or
|
||||||
// c) it's small enough to fit in that rounding delta, we're okay.
|
// c) it's small enough to fit in that rounding delta, we're okay.
|
||||||
// Otherwise treat this number as a double to avoid overflow.
|
// Otherwise treat this number as a double to avoid overflow.
|
||||||
if (value > threshold || current != token.end_ ||
|
if (value > threshold || current != token.end_ || digit > last_digit) {
|
||||||
digit > maxIntegerValue % 10) {
|
|
||||||
return decodeDouble(token, decoded);
|
return decodeDouble(token, decoded);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
value = value * 10 + digit;
|
value = value * 10 + digit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isNegative)
|
if (isNegative)
|
||||||
decoded = -Value::LargestInt(value);
|
decoded = -Value::LargestInt(value);
|
||||||
else if (value <= Value::LargestUInt(Value::maxInt))
|
else if (value <= Value::LargestUInt(Value::maxLargestInt))
|
||||||
decoded = Value::LargestInt(value);
|
decoded = Value::LargestInt(value);
|
||||||
else
|
else
|
||||||
decoded = value;
|
decoded = value;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user