[corlib] Fixed StringBuilder construction bugs in marshalling caused by changes to...
[mono.git] / mcs / class / corlib / System.Runtime.Serialization.Formatters.Binary / BinaryFormatter.cs
index 8545f81cf8315a316e31d7717695db324123698f..4d4756e150d5a16689db6d7109feaaad950c38eb 100644 (file)
@@ -36,28 +36,23 @@ using System.Security.Permissions;
 
 namespace System.Runtime.Serialization.Formatters.Binary {
 
-#if NET_2_0
        [ComVisible (true)]
+       public sealed class BinaryFormatter :
+#if !FULL_AOT_RUNTIME
+                                               IRemotingFormatter,
 #endif
-       public sealed class BinaryFormatter : IRemotingFormatter, IFormatter 
+                                               IFormatter
        {
-#if NET_2_0
                private FormatterAssemblyStyle assembly_format = FormatterAssemblyStyle.Simple;
-#else
-               private FormatterAssemblyStyle assembly_format = FormatterAssemblyStyle.Full;
-#endif
                private SerializationBinder binder;
                private StreamingContext context;
                private ISurrogateSelector surrogate_selector;
                private FormatterTypeStyle type_format = FormatterTypeStyle.TypesAlways;
-               
-#if NET_1_1
                private TypeFilterLevel filter_level = TypeFilterLevel.Full;
-#endif
                
                public BinaryFormatter()
                {
-                       surrogate_selector=null;
+                       surrogate_selector=DefaultSurrogateSelector;
                        context=new StreamingContext(StreamingContextStates.All);
                }
                
@@ -66,7 +61,17 @@ namespace System.Runtime.Serialization.Formatters.Binary {
                        surrogate_selector=selector;
                        this.context=context;
                }
+               
 
+               // Deserializing objects of type Dictionary<,> List<> and friends does not work in a CoreCLR sandbox, because
+               // the default deserialization code uses reflection to do its job, and the fields being reflected on live in mscorlib.dll.
+               // DefaultSurrogateSelector enables embedders to provide an alternative method of deserializing specific types in a way
+               // that does not violate the CoreCLR rules. See https://gist.github.com/878267 for some actual code that provides CoreCLR safe 
+               // deserialization code for List<> and Dictionary<,>.
+               // DefaultSurrogateSelector is private, and needs to be set by the embedder trough reflection, so we do not expose any public
+               // API point that is not present in .NET
+               static ISurrogateSelector DefaultSurrogateSelector { get; set; }
+               
                public FormatterAssemblyStyle AssemblyFormat
                {
                        get {
@@ -117,16 +122,11 @@ namespace System.Runtime.Serialization.Formatters.Binary {
                        }
                }
 
-#if NET_1_1
-#if !NET_2_0
-               [System.Runtime.InteropServices.ComVisible (false)]
-#endif
                public TypeFilterLevel FilterLevel 
                {
                        get { return filter_level; }
                        set { filter_level = value; }
                }
-#endif
 
                [SecurityPermission (SecurityAction.Demand, SerializationFormatter = true)]
                public object Deserialize (Stream serializationStream)
@@ -161,20 +161,20 @@ namespace System.Runtime.Serialization.Formatters.Binary {
                        // Messages are read using a special static method, which does not use ObjectReader
                        // if it is not needed. This saves time and memory.
 
-                       BinaryElement elem = (BinaryElement) reader.PeekChar();
+                       BinaryElement elem = (BinaryElement) reader.Read ();
 
                        if (elem == BinaryElement.MethodCall) {
-                               return MessageFormatter.ReadMethodCall (reader, hasHeader, handler, this);
+                               return MessageFormatter.ReadMethodCall (elem, reader, hasHeader, handler, this);
                        }
                        else if (elem == BinaryElement.MethodResponse) {
-                               return MessageFormatter.ReadMethodResponse (reader, hasHeader, handler, null, this);
+                               return MessageFormatter.ReadMethodResponse (elem, reader, hasHeader, handler, null, this);
                        }
                        else {
                                ObjectReader serializer = new ObjectReader (this);
 
                                object result;
                                Header[] headers;
-                               serializer.ReadObjectGraph (reader, hasHeader, out result, out headers);
+                               serializer.ReadObjectGraph (elem, reader, hasHeader, out result, out headers);
                                if (handler != null) handler(headers);
                                return result;
                        }
@@ -220,13 +220,13 @@ namespace System.Runtime.Serialization.Formatters.Binary {
                        WriteBinaryHeader (writer, headers!=null);
 
                        if (graph is IMethodCallMessage) {
-                               MessageFormatter.WriteMethodCall (writer, graph, headers, surrogate_selector, context, assembly_format, type_format);
+                               MessageFormatter.WriteMethodCall (writer, graph, headers, this);
                        }
                        else if (graph is IMethodReturnMessage)  {
-                               MessageFormatter.WriteMethodResponse (writer, graph, headers, surrogate_selector, context, assembly_format, type_format);
+                               MessageFormatter.WriteMethodResponse (writer, graph, headers, this);
                        }
                        else {
-                               ObjectWriter serializer = new ObjectWriter (surrogate_selector, context, assembly_format, type_format);
+                               ObjectWriter serializer = new ObjectWriter (this);
                                serializer.WriteObjectGraph (writer, graph, headers);
                        }
                        writer.Flush();
@@ -245,9 +245,9 @@ namespace System.Runtime.Serialization.Formatters.Binary {
                // shouldn't be called unless the code is intended to be executed at full-trust
                [ComVisible (false)]
                [SecurityPermission (SecurityAction.LinkDemand, SerializationFormatter = true)]
-               public object UnsafeDeserializeMethodResponse (Stream serializationStream, HeaderHandler handler, IMethodCallMessage methodCallmessage)
+               public object UnsafeDeserializeMethodResponse (Stream serializationStream, HeaderHandler handler, IMethodCallMessage methodCallMessage)
                {
-                       return NoCheckDeserializeMethodResponse (serializationStream, handler, methodCallmessage);
+                       return NoCheckDeserializeMethodResponse (serializationStream, handler, methodCallMessage);
                }
                
                private void WriteBinaryHeader (BinaryWriter writer, bool hasHeaders)