diff --git a/csharp/src/Google.Protobuf.Test/JsonParserTest.cs b/csharp/src/Google.Protobuf.Test/JsonParserTest.cs index 8462c8399477f..e170fcc5a09cd 100644 --- a/csharp/src/Google.Protobuf.Test/JsonParserTest.cs +++ b/csharp/src/Google.Protobuf.Test/JsonParserTest.cs @@ -551,13 +551,9 @@ public void NumberToDouble_Valid(string jsonValue, double expectedParsedValue) } [Test] - // Skip these test cases in .NET 5 because floating point parsing supports bigger values. - // These big values won't throw an error in the test. -#if !NETCOREAPP3_1_OR_GREATER [TestCase("1.7977e308")] [TestCase("-1.7977e308")] [TestCase("1e309")] -#endif [TestCase("1,0")] [TestCase("1.0.0")] [TestCase("+1")] diff --git a/csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs b/csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs index 7cc5c6bcfb518..df43effd4ff0f 100644 --- a/csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs +++ b/csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs @@ -199,12 +199,8 @@ public void NumberValue(string json, double expectedValue) [TestCase("1e-")] [TestCase("--")] [TestCase("--1")] - // Skip these test cases in .NET 5 because floating point parsing supports bigger values. - // These big values won't throw an error in the test. -#if !NETCOREAPP3_1_OR_GREATER [TestCase("-1.7977e308")] [TestCase("1.7977e308")] -#endif public void InvalidNumberValue(string json) { AssertThrowsAfter(json); diff --git a/csharp/src/Google.Protobuf/JsonTokenizer.cs b/csharp/src/Google.Protobuf/JsonTokenizer.cs index 4725e7cc51197..13a12c05dd44c 100644 --- a/csharp/src/Google.Protobuf/JsonTokenizer.cs +++ b/csharp/src/Google.Protobuf/JsonTokenizer.cs @@ -471,9 +471,18 @@ private double ReadNumber(char initialCharacter) // TODO: What exception should we throw if the value can't be represented as a double? try { - return double.Parse(builder.ToString(), + double result = double.Parse(builder.ToString(), NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent, CultureInfo.InvariantCulture); + + // .NET Core 3.0 and later returns infinity if the number is too large or small to be represented. + // For compatibility with other Protobuf implementations the tokenizer should still throw. + if (double.IsInfinity(result)) + { + throw reader.CreateException("Numeric value out of range: " + builder); + } + + return result; } catch (OverflowException) {