diff --git a/YamlDotNet.Test/Serialization/DeserializerTest.cs b/YamlDotNet.Test/Serialization/DeserializerTest.cs index fc49ae52..f0fd5c01 100644 --- a/YamlDotNet.Test/Serialization/DeserializerTest.cs +++ b/YamlDotNet.Test/Serialization/DeserializerTest.cs @@ -220,6 +220,44 @@ public void NewLinesInKeys() Assert.Equal($"value\na\nb", dictionary.First().Value); } + [Theory] + [InlineData(System.Byte.MinValue)] + [InlineData(System.Byte.MaxValue)] + [InlineData(System.Int16.MinValue)] + [InlineData(System.Int16.MaxValue)] + [InlineData(System.Int32.MinValue)] + [InlineData(System.Int32.MaxValue)] + [InlineData(System.Int64.MinValue)] + [InlineData(System.Int64.MaxValue)] + [InlineData(System.UInt64.MaxValue)] + [InlineData(System.Single.MinValue)] + [InlineData(System.Single.MaxValue)] + [InlineData(System.Double.MinValue)] + [InlineData(System.Double.MaxValue)] + public void UnquotedStringTypeDeserialization_RegularNumbers(object expected) + { + var deserializer = new DeserializerBuilder() + .WithAttemptingUnquotedStringTypeDeserialization().Build(); + + var yaml = $"Value: {expected}"; + +#if NETFRAMEWORK + // It needs explicitly specifying maximum precision for value roundtrip. + if (expected is float floatValue) + { + yaml = $"Value: {floatValue:G9}"; + } + if (expected is double doubleValue) + { + yaml = $"Value: {doubleValue:G17}"; + } +#endif + + var resultDict = deserializer.Deserialize>(yaml); + Assert.True(resultDict.ContainsKey("Value")); + Assert.Equal(expected, resultDict["Value"]); + } + [Theory] [InlineData(".nan", System.Single.NaN)] [InlineData(".NaN", System.Single.NaN)] diff --git a/YamlDotNet/Serialization/NodeDeserializers/ScalarNodeDeserializer.cs b/YamlDotNet/Serialization/NodeDeserializers/ScalarNodeDeserializer.cs index 95ff8f5f..fd7bcf19 100644 --- a/YamlDotNet/Serialization/NodeDeserializers/ScalarNodeDeserializer.cs +++ b/YamlDotNet/Serialization/NodeDeserializers/ScalarNodeDeserializer.cs @@ -382,13 +382,28 @@ private static object CastInteger(ulong number, TypeCode typeCode) } else if (Regex.IsMatch(v, @"[-+]?(\.[0-9]+|[0-9]+(\.[0-9]*)?)([eE][-+]?[0-9]+)?")) //regular number { - if (TryAndSwallow(() => byte.Parse(v, formatter.NumberFormat), out result)) { } - else if (TryAndSwallow(() => short.Parse(v, formatter.NumberFormat), out result)) { } - else if (TryAndSwallow(() => int.Parse(v, formatter.NumberFormat), out result)) { } - else if (TryAndSwallow(() => long.Parse(v, formatter.NumberFormat), out result)) { } - else if (TryAndSwallow(() => ulong.Parse(v, formatter.NumberFormat), out result)) { } - else if (TryAndSwallow(() => float.Parse(v, formatter.NumberFormat), out result)) { } - else if (TryAndSwallow(() => double.Parse(v, formatter.NumberFormat), out result)) { } + if (byte.TryParse(v, NumberStyles.Integer, formatter.NumberFormat, out var byteValue)) { result = byteValue; } + else if (short.TryParse(v, NumberStyles.Integer, formatter.NumberFormat, out var shortValue)) { result = shortValue; } + else if (int.TryParse(v, NumberStyles.Integer, formatter.NumberFormat, out var intValue)) { result = intValue; } + else if (long.TryParse(v, NumberStyles.Integer, formatter.NumberFormat, out var longValue)) { result = longValue; } + else if (ulong.TryParse(v, NumberStyles.Integer, formatter.NumberFormat, out var ulongValue)) { result = ulongValue; } +#if NETFRAMEWORK + else if (float.TryParse(v, NumberStyles.Float, formatter.NumberFormat, out var floatValue)) { result = floatValue; } + else if (double.TryParse(v, NumberStyles.Float, formatter.NumberFormat, out var doubleValue)) { result = doubleValue; } +#else + else if (double.TryParse(v, NumberStyles.Float, formatter.NumberFormat, out var doubleValue)) + { + var floatValue = (float)doubleValue; + if (!float.IsNaN(floatValue) && !float.IsInfinity(floatValue)) + { + result = floatValue; + } + else + { + result = doubleValue; + } + } +#endif else { //we couldn't parse it, default to string, It's probably too big