11
11
#include < json/value.h>
12
12
#endif // if !defined(JSON_IS_AMALGAMATION)
13
13
#include < cassert>
14
+ #include < cinttypes>
14
15
#include < cstring>
15
16
#include < istream>
16
17
#include < limits>
@@ -1528,15 +1529,35 @@ bool OurReader::decodeNumber(Token& token, Value& decoded) {
1528
1529
if (isNegative)
1529
1530
++current;
1530
1531
1531
- static constexpr auto positive_threshold = Value::maxLargestUInt / 10 ;
1532
- static constexpr auto positive_last_digit = Value::maxLargestUInt % 10 ;
1533
- static constexpr auto negative_threshold =
1534
- Value::LargestUInt (Value::minLargestInt) / 10 ;
1535
- static constexpr auto negative_last_digit =
1536
- Value::LargestUInt (Value::minLargestInt) % 10 ;
1537
-
1538
- const auto threshold = isNegative ? negative_threshold : positive_threshold;
1539
- const auto last_digit =
1532
+ // We assume we can represent the largest and smallest integer types as
1533
+ // unsigned integers with separate sign. This is only true if they can fit
1534
+ // into an unsigned integer.
1535
+ static_assert (Value::maxLargestInt <= Value::maxLargestUInt);
1536
+
1537
+ // We need to convert minLargestInt into a positive number. The easiest way
1538
+ // to do this conversion is to assume our "threshold" value of minLargestInt
1539
+ // divided by 10 can fit in maxLargestInt when absolute valued. This should
1540
+ // be a safe assumption.
1541
+ static_assert (Value::minLargestInt <= -Value::maxLargestInt);
1542
+ static_assert (Value::minLargestInt / 10 >= -Value::maxLargestInt);
1543
+
1544
+ static constexpr Value::LargestUInt positive_threshold =
1545
+ Value::maxLargestInt / 10 ;
1546
+ static constexpr Value::UInt positive_last_digit = Value::maxLargestInt % 10 ;
1547
+
1548
+ // For the negative values, we have to be more careful. Since typically
1549
+ // -Value::minLargestInt will cause an overflow, we first divide by 10 and
1550
+ // then take the inverse. This assumes that minLargestInt is only a single
1551
+ // power of 10 different in magnitude, which we check above. For the last
1552
+ // digit, we take the modulus before negating for the same reason.
1553
+ static const Value::LargestUInt negative_threshold =
1554
+ Value::LargestUInt (-(Value::minLargestInt / 10 ));
1555
+ static const Value::UInt negative_last_digit =
1556
+ Value::UInt (-(Value::minLargestInt % 10 ));
1557
+
1558
+ const Value::LargestUInt threshold =
1559
+ isNegative ? negative_threshold : positive_threshold;
1560
+ const Value::UInt last_digit =
1540
1561
isNegative ? negative_last_digit : positive_last_digit;
1541
1562
1542
1563
Value::LargestUInt value = 0 ;
@@ -1545,7 +1566,7 @@ bool OurReader::decodeNumber(Token& token, Value& decoded) {
1545
1566
if (c < ' 0' || c > ' 9' )
1546
1567
return decodeDouble (token, decoded);
1547
1568
1548
- const auto digit (static_cast <Value::UInt>(c - ' 0' ));
1569
+ const Value::UInt digit (static_cast <Value::UInt>(c - ' 0' ));
1549
1570
if (value >= threshold) {
1550
1571
// We've hit or exceeded the max value divided by 10 (rounded down). If
1551
1572
// a) we've only just touched the limit, meaing value == threshold,
0 commit comments