From 324c6c7f1240b6cf92e1f3215cf35e9206ec100c Mon Sep 17 00:00:00 2001 From: Levi Broderick Date: Tue, 14 Jul 2020 23:32:07 -0700 Subject: [PATCH] Obsolete BinaryFormatter.Serialize and BinaryFormatter.Deserialize (#39324) --- docs/project/list-of-obsoletions.md | 1 + src/libraries/Directory.Build.props | 6 ++++++ .../Design/DesigntimeLicenseContextSerializer.cs | 4 ++++ .../System/Configuration/SettingsPropertyValue.cs | 3 +++ .../System.Data.Common/src/System/Data/DataSet.cs | 4 ++++ .../tests/System.Data.Common.Tests.csproj | 4 ++-- .../src/System/Resources/ResourceReader.Core.cs | 1 + .../Extensions/DeserializingResourceReader.cs | 1 + .../ref/System.Runtime.Serialization.Formatters.cs | 6 ++++++ .../System.Runtime.Serialization.Formatters.csproj | 1 + .../src/System/Runtime/Serialization/Formatter.cs | 2 ++ .../Formatters/Binary/BinaryFormatter.cs | 2 ++ .../src/System/Runtime/Serialization/IFormatter.cs | 2 ++ .../src/System/Runtime/Serialization/Obsoletions.cs | 13 +++++++++++++ .../tests/FormatterTests.cs | 2 ++ .../tests/System.Runtime.Tests.csproj | 2 +- 16 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Obsoletions.cs diff --git a/docs/project/list-of-obsoletions.md b/docs/project/list-of-obsoletions.md index 40e833ae20f80..6b4d3a415ef89 100644 --- a/docs/project/list-of-obsoletions.md +++ b/docs/project/list-of-obsoletions.md @@ -15,3 +15,4 @@ Currently the identifiers `MSLIB0001` through `MSLIB0999` are carved out for obs | :--------------- | :---------- | | __`MSLIB0001`__ | The UTF-7 encoding is insecure and should not be used. Consider using UTF-8 instead. | | __`MSLIB0002`__ | `PrincipalPermissionAttribute` is not honored by the runtime and must not be used. | +| __`MSLIB0003`__ | `BinaryFormatter` serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for recommended alternatives. | diff --git a/src/libraries/Directory.Build.props b/src/libraries/Directory.Build.props index a8411eeb60d73..c46cdcdb3b190 100644 --- a/src/libraries/Directory.Build.props +++ b/src/libraries/Directory.Build.props @@ -60,6 +60,12 @@ false + + + + $(NoWarn);MSLIB0003 + + diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesigntimeLicenseContextSerializer.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesigntimeLicenseContextSerializer.cs index 1b161eccd356f..137e2d91951f9 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesigntimeLicenseContextSerializer.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesigntimeLicenseContextSerializer.cs @@ -26,14 +26,18 @@ private DesigntimeLicenseContextSerializer() public static void Serialize(Stream o, string cryptoKey, DesigntimeLicenseContext context) { IFormatter formatter = new BinaryFormatter(); +#pragma warning disable MSLIB0003 // Issue https://github.com/dotnet/runtime/issues/39293 tracks finding an alternative to BinaryFormatter formatter.Serialize(o, new object[] { cryptoKey, context._savedLicenseKeys }); +#pragma warning restore MSLIB0003 } internal static void Deserialize(Stream o, string cryptoKey, RuntimeLicenseContext context) { +#pragma warning disable MSLIB0003 // Issue https://github.com/dotnet/runtime/issues/39293 tracks finding an alternative to BinaryFormatter IFormatter formatter = new BinaryFormatter(); object obj = formatter.Deserialize(o); +#pragma warning restore MSLIB0003 if (obj is object[] value) { diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/SettingsPropertyValue.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/SettingsPropertyValue.cs index 5558f6e349ced..12849c5e9258f 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/SettingsPropertyValue.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/SettingsPropertyValue.cs @@ -98,6 +98,7 @@ private object Deserialize() { using (MemoryStream ms = new MemoryStream((byte[])SerializedValue)) { + // Issue https://github.com/dotnet/runtime/issues/39295 tracks finding an alternative to BinaryFormatter value = (new BinaryFormatter()).Deserialize(ms); } } @@ -195,6 +196,7 @@ private static object GetObjectFromString(Type type, SettingsSerializeAs seriali byte[] buffer = Convert.FromBase64String(serializedValue); using (MemoryStream ms = new MemoryStream(buffer)) { + // Issue https://github.com/dotnet/runtime/issues/39295 tracks finding an alternative to BinaryFormatter return (new BinaryFormatter()).Deserialize(ms); } case SettingsSerializeAs.Xml: @@ -221,6 +223,7 @@ private object SerializePropertyValue() using (MemoryStream ms = new MemoryStream()) { + // Issue https://github.com/dotnet/runtime/issues/39295 tracks finding an alternative to BinaryFormatter BinaryFormatter bf = new BinaryFormatter(); bf.Serialize(ms, _value); return ms.ToArray(); diff --git a/src/libraries/System.Data.Common/src/System/Data/DataSet.cs b/src/libraries/System.Data.Common/src/System/Data/DataSet.cs index 2c96c7ab89812..3bf231f8856f3 100644 --- a/src/libraries/System.Data.Common/src/System/Data/DataSet.cs +++ b/src/libraries/System.Data.Common/src/System/Data/DataSet.cs @@ -304,7 +304,9 @@ private void SerializeDataSet(SerializationInfo info, StreamingContext context, { BinaryFormatter bf = new BinaryFormatter(null, new StreamingContext(context.State, false)); MemoryStream memStream = new MemoryStream(); +#pragma warning disable MSLIB0003 // Issue https://github.com/dotnet/runtime/issues/39289 tracks finding an alternative to BinaryFormatter bf.Serialize(memStream, Tables[i]); +#pragma warning restore MSLIB0003 memStream.Position = 0; info.AddValue(string.Format(CultureInfo.InvariantCulture, "DataSet.Tables_{0}", i), memStream.GetBuffer()); } @@ -382,7 +384,9 @@ private void DeserializeDataSetSchema(SerializationInfo info, StreamingContext c MemoryStream memStream = new MemoryStream(buffer); memStream.Position = 0; BinaryFormatter bf = new BinaryFormatter(null, new StreamingContext(context.State, false)); +#pragma warning disable MSLIB0003 // Issue https://github.com/dotnet/runtime/issues/39289 tracks finding an alternative to BinaryFormatter DataTable dt = (DataTable)bf.Deserialize(memStream); +#pragma warning restore MSLIB0003 Tables.Add(dt); } diff --git a/src/libraries/System.Data.Common/tests/System.Data.Common.Tests.csproj b/src/libraries/System.Data.Common/tests/System.Data.Common.Tests.csproj index 4d0933db75b09..533f17e39b195 100644 --- a/src/libraries/System.Data.Common/tests/System.Data.Common.Tests.csproj +++ b/src/libraries/System.Data.Common/tests/System.Data.Common.Tests.csproj @@ -1,6 +1,6 @@ - + - 0168,0169,0414,0219,0649 + $(NoWarn),0168,0169,0414,0219,0649 true $(NetCoreAppCurrent) diff --git a/src/libraries/System.Private.CoreLib/src/System/Resources/ResourceReader.Core.cs b/src/libraries/System.Private.CoreLib/src/System/Resources/ResourceReader.Core.cs index 0a91938f83b14..c76a8b6f15004 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Resources/ResourceReader.Core.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Resources/ResourceReader.Core.cs @@ -64,6 +64,7 @@ private object DeserializeObject(int typeIndex) return graph; } + // Issue https://github.com/dotnet/runtime/issues/39290 tracks finding an alternative to BinaryFormatter private void InitializeBinaryFormatter() { LazyInitializer.EnsureInitialized(ref s_binaryFormatterType, () => diff --git a/src/libraries/System.Resources.Extensions/src/System/Resources/Extensions/DeserializingResourceReader.cs b/src/libraries/System.Resources.Extensions/src/System/Resources/Extensions/DeserializingResourceReader.cs index defc47de9c910..da143cb11b3e2 100644 --- a/src/libraries/System.Resources.Extensions/src/System/Resources/Extensions/DeserializingResourceReader.cs +++ b/src/libraries/System.Resources.Extensions/src/System/Resources/Extensions/DeserializingResourceReader.cs @@ -34,6 +34,7 @@ private bool ValidateReaderType(string readerType) return false; } + // Issue https://github.com/dotnet/runtime/issues/39292 tracks finding an alternative to BinaryFormatter private object ReadBinaryFormattedObject() { if (_formatter == null) diff --git a/src/libraries/System.Runtime.Serialization.Formatters/ref/System.Runtime.Serialization.Formatters.cs b/src/libraries/System.Runtime.Serialization.Formatters/ref/System.Runtime.Serialization.Formatters.cs index 78cece9ec4fd7..4681ba9721b76 100644 --- a/src/libraries/System.Runtime.Serialization.Formatters/ref/System.Runtime.Serialization.Formatters.cs +++ b/src/libraries/System.Runtime.Serialization.Formatters/ref/System.Runtime.Serialization.Formatters.cs @@ -15,9 +15,11 @@ protected Formatter() { } public abstract System.Runtime.Serialization.SerializationBinder? Binder { get; set; } public abstract System.Runtime.Serialization.StreamingContext Context { get; set; } public abstract System.Runtime.Serialization.ISurrogateSelector? SurrogateSelector { get; set; } + [System.ObsoleteAttribute("BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information.", DiagnosticId = "MSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] public abstract object Deserialize(System.IO.Stream serializationStream); protected virtual object? GetNext(out long objID) { throw null; } protected virtual long Schedule(object? obj) { throw null; } + [System.ObsoleteAttribute("BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information.", DiagnosticId = "MSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] public abstract void Serialize(System.IO.Stream serializationStream, object graph); protected abstract void WriteArray(object obj, string name, System.Type memberType); protected abstract void WriteBoolean(bool val, string name); @@ -85,7 +87,9 @@ public partial interface IFormatter System.Runtime.Serialization.SerializationBinder? Binder { get; set; } System.Runtime.Serialization.StreamingContext Context { get; set; } System.Runtime.Serialization.ISurrogateSelector? SurrogateSelector { get; set; } + [System.ObsoleteAttribute("BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information.", DiagnosticId = "MSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] object Deserialize(System.IO.Stream serializationStream); + [System.ObsoleteAttribute("BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information.", DiagnosticId = "MSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] void Serialize(System.IO.Stream serializationStream, object graph); } public partial interface ISerializationSurrogate @@ -179,7 +183,9 @@ public BinaryFormatter(System.Runtime.Serialization.ISurrogateSelector? selector public System.Runtime.Serialization.Formatters.TypeFilterLevel FilterLevel { get { throw null; } set { } } public System.Runtime.Serialization.ISurrogateSelector? SurrogateSelector { get { throw null; } set { } } public System.Runtime.Serialization.Formatters.FormatterTypeStyle TypeFormat { get { throw null; } set { } } + [System.ObsoleteAttribute("BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information.", DiagnosticId = "MSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] public object Deserialize(System.IO.Stream serializationStream) { throw null; } + [System.ObsoleteAttribute("BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information.", DiagnosticId = "MSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] public void Serialize(System.IO.Stream serializationStream, object graph) { } } } diff --git a/src/libraries/System.Runtime.Serialization.Formatters/src/System.Runtime.Serialization.Formatters.csproj b/src/libraries/System.Runtime.Serialization.Formatters/src/System.Runtime.Serialization.Formatters.csproj index e39003d146ac3..e7f6a3fffb737 100644 --- a/src/libraries/System.Runtime.Serialization.Formatters/src/System.Runtime.Serialization.Formatters.csproj +++ b/src/libraries/System.Runtime.Serialization.Formatters/src/System.Runtime.Serialization.Formatters.csproj @@ -17,6 +17,7 @@ + diff --git a/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatter.cs b/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatter.cs index fb744211f5c6e..1fa2c68d14bcc 100644 --- a/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatter.cs +++ b/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatter.cs @@ -20,6 +20,7 @@ protected Formatter() m_idGenerator = new ObjectIDGenerator(); } + [Obsolete(Obsoletions.InsecureSerializationMessage, DiagnosticId = Obsoletions.InsecureSerializationDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] public abstract object Deserialize(Stream serializationStream); protected virtual object? GetNext(out long objID) @@ -59,6 +60,7 @@ protected virtual long Schedule(object? obj) return id; } + [Obsolete(Obsoletions.InsecureSerializationMessage, DiagnosticId = Obsoletions.InsecureSerializationDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] public abstract void Serialize(Stream serializationStream, object graph); protected abstract void WriteArray(object obj, string name, Type memberType); diff --git a/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryFormatter.cs b/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryFormatter.cs index a44c8b692a459..5ca47d5abd29c 100644 --- a/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryFormatter.cs +++ b/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryFormatter.cs @@ -37,6 +37,7 @@ public BinaryFormatter(ISurrogateSelector? selector, StreamingContext context) _context = context; } + [Obsolete(Obsoletions.InsecureSerializationMessage, DiagnosticId = Obsoletions.InsecureSerializationDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] public object Deserialize(Stream serializationStream) => Deserialize(serializationStream, true); internal object Deserialize(Stream serializationStream, bool check) @@ -77,6 +78,7 @@ internal object Deserialize(Stream serializationStream, bool check) } } + [Obsolete(Obsoletions.InsecureSerializationMessage, DiagnosticId = Obsoletions.InsecureSerializationDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] public void Serialize(Stream serializationStream, object graph) => Serialize(serializationStream, graph, true); diff --git a/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/IFormatter.cs b/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/IFormatter.cs index 59c516c58f97e..7fd7f9e3d478a 100644 --- a/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/IFormatter.cs +++ b/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/IFormatter.cs @@ -7,7 +7,9 @@ namespace System.Runtime.Serialization { public interface IFormatter { + [Obsolete(Obsoletions.InsecureSerializationMessage, DiagnosticId = Obsoletions.InsecureSerializationDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] object Deserialize(Stream serializationStream); + [Obsolete(Obsoletions.InsecureSerializationMessage, DiagnosticId = Obsoletions.InsecureSerializationDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] void Serialize(Stream serializationStream, object graph); ISurrogateSelector? SurrogateSelector { get; set; } SerializationBinder? Binder { get; set; } diff --git a/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Obsoletions.cs b/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Obsoletions.cs new file mode 100644 index 0000000000000..191d0fa071d99 --- /dev/null +++ b/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Obsoletions.cs @@ -0,0 +1,13 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Runtime.Serialization +{ + internal static class Obsoletions + { + internal const string SharedUrlFormat = "https://aka.ms/dotnet-warnings/{0}"; + + internal const string InsecureSerializationMessage = "BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information."; + internal const string InsecureSerializationDiagId = "MSLIB0003"; + } +} diff --git a/src/libraries/System.Runtime.Serialization.Formatters/tests/FormatterTests.cs b/src/libraries/System.Runtime.Serialization.Formatters/tests/FormatterTests.cs index eb06d7582efd6..68ca34ee79d6a 100644 --- a/src/libraries/System.Runtime.Serialization.Formatters/tests/FormatterTests.cs +++ b/src/libraries/System.Runtime.Serialization.Formatters/tests/FormatterTests.cs @@ -140,8 +140,10 @@ private sealed class TestFormatter : Formatter public override SerializationBinder Binder { get; set; } public override StreamingContext Context { get; set; } public override ISurrogateSelector SurrogateSelector { get; set; } +#pragma warning disable CS0672 // Member overrides obsolete member public override object Deserialize(Stream serializationStream) => null; public override void Serialize(Stream serializationStream, object graph) { } +#pragma warning restore CS0672 // Member overrides obsolete member } } } diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj b/src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj index e58be38fd7424..39ca7313460b8 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj @@ -1,7 +1,7 @@ true - 1718 + $(NoWarn),1718 true true $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser