From c8d9b20fd20caa826ba8ba139d51dd472d227e22 Mon Sep 17 00:00:00 2001 From: TalAloni Date: Fri, 1 Jan 2021 22:18:26 +0200 Subject: [PATCH 1/9] Bugfix: System.Xml.Serialization: Compiler.GetTempAssemblyName is not persistent under .NET Core The implementation of String.GetHashCode() was persistent by default in .NET Framework. allowing to predictably name an XmlSerializers.{HashCode}.dll containing the pre-generated serializers. In .NET Core / .NET 5, String.GetHashCode() is no longer persistent, so the value of ns.GetHashCode() will change during each run, preventing it from picking up the XmlSerializers dll correctly. --- .../src/System/Xml/Serialization/Compiler.cs | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compiler.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compiler.cs index 890628ad68afc1..95890e9a78feb5 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compiler.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compiler.cs @@ -87,7 +87,25 @@ internal TextWriter Source internal static string GetTempAssemblyName(AssemblyName parent, string? ns) { - return parent.Name + ".XmlSerializers" + (ns == null || ns.Length == 0 ? "" : "." + ns.GetHashCode()); + return parent.Name + ".XmlSerializers" + (ns == null || ns.Length == 0 ? "" : "." + GetPersistentHashCode(ns)); + } + + /// + /// Returns the same value returned by .NET Framework 64-bit String.GetHashCode() + /// + private static int GetPersistentHashCode(string value) + { + int hash1 = 5381; + int hash2 = hash1; + + for (int i = 0; i < value.Length && value[i] != '\0'; i += 2) + { + hash1 = ((hash1 << 5) + hash1) ^ value[i]; + if (i == value.Length - 1 || value[i + 1] == '\0') + break; + hash2 = ((hash2 << 5) + hash2) ^ value[i + 1]; + } + return hash1 + (hash2 * 1566083941); } } } From 49327d3ef8e093a3d075fcd426d41eea9aac6f48 Mon Sep 17 00:00:00 2001 From: TalAloni Date: Sat, 2 Jan 2021 00:55:01 +0200 Subject: [PATCH 2/9] Remove trailing whitespace --- .../System.Private.Xml/src/System/Xml/Serialization/Compiler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compiler.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compiler.cs index 95890e9a78feb5..da1715bd41875e 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compiler.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compiler.cs @@ -89,7 +89,7 @@ internal static string GetTempAssemblyName(AssemblyName parent, string? ns) { return parent.Name + ".XmlSerializers" + (ns == null || ns.Length == 0 ? "" : "." + GetPersistentHashCode(ns)); } - + /// /// Returns the same value returned by .NET Framework 64-bit String.GetHashCode() /// From 384ceac9b60633268d868803eb346121331f74cd Mon Sep 17 00:00:00 2001 From: TalAloni Date: Sat, 20 Feb 2021 12:09:40 +0200 Subject: [PATCH 3/9] Use truncated SHA512 --- .../src/System/Xml/Serialization/Compiler.cs | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compiler.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compiler.cs index da1715bd41875e..8a60b436574b17 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compiler.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compiler.cs @@ -90,22 +90,11 @@ internal static string GetTempAssemblyName(AssemblyName parent, string? ns) return parent.Name + ".XmlSerializers" + (ns == null || ns.Length == 0 ? "" : "." + GetPersistentHashCode(ns)); } - /// - /// Returns the same value returned by .NET Framework 64-bit String.GetHashCode() - /// - private static int GetPersistentHashCode(string value) + private static uint GetPersistentHashCode(string value) { - int hash1 = 5381; - int hash2 = hash1; - - for (int i = 0; i < value.Length && value[i] != '\0'; i += 2) - { - hash1 = ((hash1 << 5) + hash1) ^ value[i]; - if (i == value.Length - 1 || value[i + 1] == '\0') - break; - hash2 = ((hash2 << 5) + hash2) ^ value[i + 1]; - } - return hash1 + (hash2 * 1566083941); + byte[] valueBytes = Encoding.UTF8.GetBytes(value); + byte[] hash = System.Security.Cryptography.SHA512.Create().ComputeHash(valueBytes); + return (uint)(hash[0] << 24 | hash[1] << 16 | hash[2] << 8 | hash[3]); } } } From bfb2139b023c309c78e546af3b9708258ca1a81b Mon Sep 17 00:00:00 2001 From: TalAloni Date: Sat, 20 Feb 2021 18:16:23 +0200 Subject: [PATCH 4/9] Fixed compilation --- .../System.Private.Xml/src/System/Xml/Serialization/Compiler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compiler.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compiler.cs index 8a60b436574b17..e5cc12b4ac5937 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compiler.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compiler.cs @@ -92,7 +92,7 @@ internal static string GetTempAssemblyName(AssemblyName parent, string? ns) private static uint GetPersistentHashCode(string value) { - byte[] valueBytes = Encoding.UTF8.GetBytes(value); + byte[] valueBytes = System.Text.Encoding.UTF8.GetBytes(value); byte[] hash = System.Security.Cryptography.SHA512.Create().ComputeHash(valueBytes); return (uint)(hash[0] << 24 | hash[1] << 16 | hash[2] << 8 | hash[3]); } From a86258b37ef7cd33e8783070d2d5406530ea0608 Mon Sep 17 00:00:00 2001 From: TalAloni Date: Sat, 20 Feb 2021 18:20:12 +0200 Subject: [PATCH 5/9] Dispose SHA512 instance --- .../src/System/Xml/Serialization/Compiler.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compiler.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compiler.cs index e5cc12b4ac5937..04a13dbd27021c 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compiler.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compiler.cs @@ -7,6 +7,7 @@ using System.Diagnostics; using System.Globalization; using System.Runtime.CompilerServices; +using System.Security.Cryptography; namespace System.Xml.Serialization { @@ -93,8 +94,11 @@ internal static string GetTempAssemblyName(AssemblyName parent, string? ns) private static uint GetPersistentHashCode(string value) { byte[] valueBytes = System.Text.Encoding.UTF8.GetBytes(value); - byte[] hash = System.Security.Cryptography.SHA512.Create().ComputeHash(valueBytes); - return (uint)(hash[0] << 24 | hash[1] << 16 | hash[2] << 8 | hash[3]); + using (SHA512 sha512 = SHA512.Create()) + { + byte[] hash = sha512.ComputeHash(valueBytes); + return (uint)(hash[0] << 24 | hash[1] << 16 | hash[2] << 8 | hash[3]); + } } } } From ef862696bcca76d97edf30d8fc37d2ad0e66d1f1 Mon Sep 17 00:00:00 2001 From: TalAloni Date: Sat, 20 Feb 2021 19:19:51 +0200 Subject: [PATCH 6/9] Fixed compilation --- src/libraries/System.Private.Xml/src/System.Private.Xml.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libraries/System.Private.Xml/src/System.Private.Xml.csproj b/src/libraries/System.Private.Xml/src/System.Private.Xml.csproj index 9585e677104d1b..f5283317bff2b2 100644 --- a/src/libraries/System.Private.Xml/src/System.Private.Xml.csproj +++ b/src/libraries/System.Private.Xml/src/System.Private.Xml.csproj @@ -572,6 +572,7 @@ + From 5ab93447d7f00d21792b3ecac36a579b82fad081 Mon Sep 17 00:00:00 2001 From: Tal Aloni Date: Fri, 9 Jul 2021 19:17:38 +0300 Subject: [PATCH 7/9] Update src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compiler.cs Co-authored-by: Stephen Toub --- .../src/System/Xml/Serialization/Compiler.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compiler.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compiler.cs index d653d59fd0f814..8adcd02c8c2cf3 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compiler.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compiler.cs @@ -96,11 +96,8 @@ internal static string GetTempAssemblyName(AssemblyName parent, string? ns) private static uint GetPersistentHashCode(string value) { byte[] valueBytes = System.Text.Encoding.UTF8.GetBytes(value); - using (SHA512 sha512 = SHA512.Create()) - { - byte[] hash = sha512.ComputeHash(valueBytes); - return (uint)(hash[0] << 24 | hash[1] << 16 | hash[2] << 8 | hash[3]); - } + byte[] hash = SHA512.HashData(valueBytes); + return (uint)(hash[0] << 24 | hash[1] << 16 | hash[2] << 8 | hash[3]); } } } From 1e057b4e68c76c8ee8acc14dacddad1e24b0373f Mon Sep 17 00:00:00 2001 From: Tal Aloni Date: Fri, 9 Jul 2021 19:18:24 +0300 Subject: [PATCH 8/9] Update src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compiler.cs Co-authored-by: Stephen Toub --- .../System.Private.Xml/src/System/Xml/Serialization/Compiler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compiler.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compiler.cs index 8adcd02c8c2cf3..e58eb7d707d1ae 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compiler.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compiler.cs @@ -90,7 +90,7 @@ internal TextWriter Source internal static string GetTempAssemblyName(AssemblyName parent, string? ns) { - return parent.Name + ".XmlSerializers" + (ns == null || ns.Length == 0 ? "" : "." + GetPersistentHashCode(ns)); + return parent.Name + ".XmlSerializers" + (string.IsNullOrEmpty(ns) ? "" : $".{GetPersistentHashCode(ns)}"); } private static uint GetPersistentHashCode(string value) From 7a96f187e8649653f8efb9ac831aeb48d8451327 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Sun, 18 Jul 2021 06:37:59 -0400 Subject: [PATCH 9/9] Update Compiler.cs --- .../src/System/Xml/Serialization/Compiler.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compiler.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compiler.cs index e58eb7d707d1ae..71e2fdd1ed1fef 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compiler.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compiler.cs @@ -1,14 +1,16 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Reflection; +using System.Buffers.Binary; using System.Collections; -using System.IO; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Globalization; +using System.IO; +using System.Reflection; using System.Runtime.CompilerServices; -using System.Diagnostics.CodeAnalysis; using System.Security.Cryptography; +using System.Text; namespace System.Xml.Serialization { @@ -95,9 +97,9 @@ internal static string GetTempAssemblyName(AssemblyName parent, string? ns) private static uint GetPersistentHashCode(string value) { - byte[] valueBytes = System.Text.Encoding.UTF8.GetBytes(value); + byte[] valueBytes = Encoding.UTF8.GetBytes(value); byte[] hash = SHA512.HashData(valueBytes); - return (uint)(hash[0] << 24 | hash[1] << 16 | hash[2] << 8 | hash[3]); + return BinaryPrimitives.ReadUInt32BigEndian(hash); } } }