diff --git a/Parse.Tests/JsonTests.cs b/Parse.Tests/JsonTests.cs index ef67f6e8..49688cb1 100644 --- a/Parse.Tests/JsonTests.cs +++ b/Parse.Tests/JsonTests.cs @@ -1,6 +1,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Globalization; using Microsoft.VisualStudio.TestTools.UnitTesting; using Parse.Infrastructure.Utilities; @@ -250,5 +251,29 @@ public void TestSpecialJsonNumbersAndModifiers() Assert.AreEqual(123456789123456789, (JsonUtilities.Parse("{ \"mura\": 123456789123456789 }") as IDictionary)["mura"]); } + + + [TestMethod] + public void TestJsonNumbersAndValueRanges() + { + //Assert.ThrowsException(() => JsonUtilities.Parse("+123456789")); + Assert.IsInstanceOfType((JsonUtilities.Parse("{ \"long\": " + long.MaxValue + " }") as IDictionary)["long"], typeof(long)); + Assert.IsInstanceOfType((JsonUtilities.Parse("{ \"long\": " + long.MinValue + " }") as IDictionary)["long"], typeof(long)); + + Assert.AreEqual((JsonUtilities.Parse("{ \"long\": " + long.MaxValue + " }") as IDictionary)["long"], long.MaxValue); + Assert.AreEqual((JsonUtilities.Parse("{ \"long\": " + long.MinValue + " }") as IDictionary)["long"], long.MinValue); + + + Assert.IsInstanceOfType((JsonUtilities.Parse("{ \"double\": " + double.MaxValue.ToString(CultureInfo.InvariantCulture) + " }") as IDictionary)["double"], typeof(double)); + Assert.IsInstanceOfType((JsonUtilities.Parse("{ \"double\": " + double.MinValue.ToString(CultureInfo.InvariantCulture) + " }") as IDictionary)["double"], typeof(double)); + + Assert.AreEqual((JsonUtilities.Parse("{ \"double\": " + double.MaxValue.ToString(CultureInfo.InvariantCulture) + " }") as IDictionary)["double"], double.MaxValue); + Assert.AreEqual((JsonUtilities.Parse("{ \"double\": " + double.MinValue.ToString(CultureInfo.InvariantCulture) + " }") as IDictionary)["double"], double.MinValue); + + double outOfInt64RangeValue = -9223372036854776000d; + Assert.IsInstanceOfType((JsonUtilities.Parse("{ \"double\": " + outOfInt64RangeValue.ToString(CultureInfo.InvariantCulture) + " }") as IDictionary)["double"], typeof(double)); + Assert.AreEqual((JsonUtilities.Parse("{ \"double\": " + outOfInt64RangeValue.ToString(CultureInfo.InvariantCulture) + " }") as IDictionary)["double"], outOfInt64RangeValue); + } + } } diff --git a/Parse/Infrastructure/Utilities/JsonUtilities.cs b/Parse/Infrastructure/Utilities/JsonUtilities.cs index 3f7d5a79..585e2110 100644 --- a/Parse/Infrastructure/Utilities/JsonUtilities.cs +++ b/Parse/Infrastructure/Utilities/JsonUtilities.cs @@ -212,8 +212,20 @@ private bool ParseNumber(out object output) } else { - output = Int64.Parse(m.Value, CultureInfo.InvariantCulture); - return true; + // try to parse to a long assuming it is an integer value (this might fail due to value range differences when storing as double without decimal point or exponent) + if (Int64.TryParse(m.Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out long longValue)) + { + output = longValue; + return true; + } + // try to parse as double again (most likely due to value range exceeding long type + else if (Double.TryParse(m.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out double doubleValue)) + { + output = doubleValue; + return true; + } + else + return false; } }