From 97076d89c2c5350a45a2ee5ae7e69e7d139a8063 Mon Sep 17 00:00:00 2001 From: Huangli Wu Date: Fri, 18 Aug 2017 17:32:08 -0700 Subject: [PATCH] Fix the sgen issue when use NaN as the default value. (#23366) * Fix the codegen issue when use NaN as the default value. Move the NaN test from runtimeonly to XmlTest so it will be included in Sgen test run. * Add brackets. --- .../Generator/XmlSerializationWriter.cs | 22 ++++++++++++-- .../XmlSerializerTests.RuntimeOnly.cs | 16 ---------- .../tests/XmlSerializer/XmlSerializerTests.cs | 16 ++++++++++ .../tests/SerializationTypes.RuntimeOnly.cs | 29 ------------------- .../tests/SerializationTypes.cs | 29 +++++++++++++++++++ 5 files changed, 64 insertions(+), 48 deletions(-) diff --git a/src/Microsoft.XmlSerializer.Generator/src/Microsoft/XmlSerializer/Generator/XmlSerializationWriter.cs b/src/Microsoft.XmlSerializer.Generator/src/Microsoft/XmlSerializer/Generator/XmlSerializationWriter.cs index 13f85cf60999..22c8fe63366f 100644 --- a/src/Microsoft.XmlSerializer.Generator/src/Microsoft/XmlSerializer/Generator/XmlSerializationWriter.cs +++ b/src/Microsoft.XmlSerializer.Generator/src/Microsoft/XmlSerializer/Generator/XmlSerializationWriter.cs @@ -2044,7 +2044,16 @@ private void WriteValue(object value) else if (type == typeof(Int32)) Writer.Write(((Int32)value).ToString(null, NumberFormatInfo.InvariantInfo)); else if (type == typeof(Double)) - Writer.Write(((Double)value).ToString("R", NumberFormatInfo.InvariantInfo)); + { + if (double.IsNaN((Double)value)) + { + Writer.Write("double.NaN"); + } + else + { + Writer.Write(((Double)value).ToString("R", NumberFormatInfo.InvariantInfo)); + } + } else if (type == typeof(Boolean)) Writer.Write((bool)value ? "true" : "false"); else if ((type == typeof(Int16)) || (type == typeof(Int64)) || (type == typeof(UInt16)) || (type == typeof(UInt32)) || (type == typeof(UInt64)) || (type == typeof(Byte)) || (type == typeof(SByte))) @@ -2058,8 +2067,15 @@ private void WriteValue(object value) } else if (type == typeof(Single)) { - Writer.Write(((Single)value).ToString("R", NumberFormatInfo.InvariantInfo)); - Writer.Write("f"); + if (Single.IsNaN((Single)value)) + { + Writer.Write("System.Single.NaN"); + } + else + { + Writer.Write(((Single)value).ToString("R", NumberFormatInfo.InvariantInfo)); + Writer.Write("f"); + } } else if (type == typeof(Decimal)) { diff --git a/src/System.Private.Xml/tests/XmlSerializer/XmlSerializerTests.RuntimeOnly.cs b/src/System.Private.Xml/tests/XmlSerializer/XmlSerializerTests.RuntimeOnly.cs index 2eeb8105b34d..12f7036c9fd7 100644 --- a/src/System.Private.Xml/tests/XmlSerializer/XmlSerializerTests.RuntimeOnly.cs +++ b/src/System.Private.Xml/tests/XmlSerializer/XmlSerializerTests.RuntimeOnly.cs @@ -2036,22 +2036,6 @@ public static void XmlMembersMapping_CompositeType() Assert.Equal(requestBodyValue.composite.StringValue, requestBodyActual.composite.StringValue); } - [Fact] - public static void Xml_DefaultValueAttributeSetToNaNTest() - { - var value = new DefaultValuesSetToNaN(); - var actual = SerializeAndDeserialize(value, -@" - - 0 - 0 - 0 - 0 -"); - Assert.NotNull(actual); - Assert.Equal(value, actual); - } - [Fact] public static void XmlMembersMapping_SimpleType_HasWrapperElement() { diff --git a/src/System.Private.Xml/tests/XmlSerializer/XmlSerializerTests.cs b/src/System.Private.Xml/tests/XmlSerializer/XmlSerializerTests.cs index 57bf65fdb7f8..69f16e4d3462 100644 --- a/src/System.Private.Xml/tests/XmlSerializer/XmlSerializerTests.cs +++ b/src/System.Private.Xml/tests/XmlSerializer/XmlSerializerTests.cs @@ -1612,6 +1612,22 @@ public static void Xml_Soap_TypeWithMyCollectionField() Assert.True(value.Collection.SequenceEqual(actual.Collection)); } + [Fact] + public static void Xml_DefaultValueAttributeSetToNaNTest() + { + var value = new DefaultValuesSetToNaN(); + var actual = SerializeAndDeserialize(value, +@" + + 0 + 0 + 0 + 0 +"); + Assert.NotNull(actual); + Assert.Equal(value, actual); + } + private static readonly string s_defaultNs = "http://tempuri.org/"; private static T RoundTripWithXmlMembersMapping(object requestBodyValue, string memberName, string baseline, bool skipStringCompare = false, string wrapperName = null) { diff --git a/src/System.Runtime.Serialization.Xml/tests/SerializationTypes.RuntimeOnly.cs b/src/System.Runtime.Serialization.Xml/tests/SerializationTypes.RuntimeOnly.cs index ff987d195846..a14051d7d63e 100644 --- a/src/System.Runtime.Serialization.Xml/tests/SerializationTypes.RuntimeOnly.cs +++ b/src/System.Runtime.Serialization.Xml/tests/SerializationTypes.RuntimeOnly.cs @@ -3553,35 +3553,6 @@ public void GetObjectData(SerializationInfo info, StreamingContext context) } } -public class DefaultValuesSetToNaN -{ - [DefaultValue(double.NaN)] - public double DoubleProp { get; set; } - - [DefaultValue(float.NaN)] - public float FloatProp { get; set; } - - [DefaultValue(Double.NaN)] - public Double DoubleField; - - [DefaultValue(Single.NaN)] - public Single SingleField; - - public override bool Equals(object obj) - { - var other = obj as DefaultValuesSetToNaN; - return other == null ? false : - other.DoubleProp == this.DoubleProp && other.FloatProp == this.FloatProp && - other.DoubleField == this.DoubleField && other.SingleField == this.SingleField; - } - - public override int GetHashCode() - { - return this.DoubleProp.GetHashCode() ^ this.FloatProp.GetHashCode() ^ - this.DoubleField.GetHashCode() ^ this.SingleField.GetHashCode(); - } -} - public class JsonTypes { public Dictionary StringKeyValue diff --git a/src/System.Runtime.Serialization.Xml/tests/SerializationTypes.cs b/src/System.Runtime.Serialization.Xml/tests/SerializationTypes.cs index 12cc5fbc2a8b..85e16aec4e68 100644 --- a/src/System.Runtime.Serialization.Xml/tests/SerializationTypes.cs +++ b/src/System.Runtime.Serialization.Xml/tests/SerializationTypes.cs @@ -1134,4 +1134,33 @@ public class TypeWithVirtualGenericProperty public class TypeWithVirtualGenericPropertyDerived : TypeWithVirtualGenericProperty { public override T Value { get; set; } +} + +public class DefaultValuesSetToNaN +{ + [DefaultValue(double.NaN)] + public double DoubleProp { get; set; } + + [DefaultValue(float.NaN)] + public float FloatProp { get; set; } + + [DefaultValue(Double.NaN)] + public Double DoubleField; + + [DefaultValue(Single.NaN)] + public Single SingleField; + + public override bool Equals(object obj) + { + var other = obj as DefaultValuesSetToNaN; + return other == null ? false : + other.DoubleProp == this.DoubleProp && other.FloatProp == this.FloatProp && + other.DoubleField == this.DoubleField && other.SingleField == this.SingleField; + } + + public override int GetHashCode() + { + return this.DoubleProp.GetHashCode() ^ this.FloatProp.GetHashCode() ^ + this.DoubleField.GetHashCode() ^ this.SingleField.GetHashCode(); + } } \ No newline at end of file