De-serialization of Decimal not always overflowing when it should (#1668)

This commit is contained in:
Tyler Brinkley
2018-04-22 12:28:15 +12:00
committed by James Newton-King
parent 4c4d870816
commit 94a4dbf7fe
2 changed files with 10 additions and 4 deletions
@@ -233,6 +233,8 @@ namespace Newtonsoft.Json.Tests.Utilities
AssertDecimalTryParse("1E+29", ParseResult.Overflow, null); AssertDecimalTryParse("1E+29", ParseResult.Overflow, null);
AssertDecimalTryParse("-1E+29", ParseResult.Overflow, null); AssertDecimalTryParse("-1E+29", ParseResult.Overflow, null);
AssertDecimalTryParse("79228162514264337593543950336", ParseResult.Overflow, null); // decimal.MaxValue + 1
AssertDecimalTryParse("-79228162514264337593543950336", ParseResult.Overflow, null); // decimal.MinValue - 1
AssertDecimalTryParse("1-1", ParseResult.Invalid, null); AssertDecimalTryParse("1-1", ParseResult.Invalid, null);
AssertDecimalTryParse("1-", ParseResult.Invalid, null); AssertDecimalTryParse("1-", ParseResult.Invalid, null);
@@ -1334,7 +1334,7 @@ namespace Newtonsoft.Json.Utilities
ulong lo10 = 0UL; ulong lo10 = 0UL;
int mantissaDigits = 0; int mantissaDigits = 0;
int exponentFromMantissa = 0; int exponentFromMantissa = 0;
bool? roundUp = null; char? digit29 = null;
bool? storeOnly28Digits = null; bool? storeOnly28Digits = null;
for (; i < end; i++) for (; i < end; i++)
{ {
@@ -1455,9 +1455,9 @@ namespace Newtonsoft.Json.Utilities
} }
else else
{ {
if (!roundUp.HasValue) if (!digit29.HasValue)
{ {
roundUp = c >= '5'; digit29 = c;
} }
++exponentFromMantissa; ++exponentFromMantissa;
} }
@@ -1496,6 +1496,10 @@ namespace Newtonsoft.Json.Utilities
return ParseResult.Overflow; return ParseResult.Overflow;
} }
} }
else if (value == decimalMaxValueHi28 && digit29 > decimalMaxValueLo1)
{
return ParseResult.Overflow;
}
value *= 10M; value *= 10M;
} }
else else
@@ -1505,7 +1509,7 @@ namespace Newtonsoft.Json.Utilities
} }
else else
{ {
if (roundUp == true && exponent >= -28) if (digit29 >= '5' && exponent >= -28)
{ {
++value; ++value;
} }