summaryrefslogtreecommitdiff
path: root/src/mscorlib/src/System/Runtime/Serialization
diff options
context:
space:
mode:
Diffstat (limited to 'src/mscorlib/src/System/Runtime/Serialization')
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/FormatterConverter.cs34
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/FormatterServices.cs76
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/IObjectReference.cs1
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/ISerializable.cs1
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/ISerializationSurrogate.cs2
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/ISurrogateSelector.cs3
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/SafeSerializationManager.cs446
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/SerializationFieldInfo.cs36
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/SerializationInfo.cs98
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/SerializationInfoEnumerator.cs15
10 files changed, 529 insertions, 183 deletions
diff --git a/src/mscorlib/src/System/Runtime/Serialization/FormatterConverter.cs b/src/mscorlib/src/System/Runtime/Serialization/FormatterConverter.cs
index 7df221c9cd..b710ed0b3a 100644
--- a/src/mscorlib/src/System/Runtime/Serialization/FormatterConverter.cs
+++ b/src/mscorlib/src/System/Runtime/Serialization/FormatterConverter.cs
@@ -25,7 +25,7 @@ namespace System.Runtime.Serialization {
public Object Convert(Object value, Type type) {
if (value==null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ChangeType(value, type, CultureInfo.InvariantCulture);
@@ -33,7 +33,7 @@ namespace System.Runtime.Serialization {
public Object Convert(Object value, TypeCode typeCode) {
if (value==null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ChangeType(value, typeCode, CultureInfo.InvariantCulture);
@@ -41,7 +41,7 @@ namespace System.Runtime.Serialization {
public bool ToBoolean(Object value) {
if (value==null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ToBoolean(value, CultureInfo.InvariantCulture);
@@ -49,7 +49,7 @@ namespace System.Runtime.Serialization {
public char ToChar(Object value) {
if (value==null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ToChar(value, CultureInfo.InvariantCulture);
@@ -58,7 +58,7 @@ namespace System.Runtime.Serialization {
[CLSCompliant(false)]
public sbyte ToSByte(Object value) {
if (value==null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ToSByte(value, CultureInfo.InvariantCulture);
@@ -66,7 +66,7 @@ namespace System.Runtime.Serialization {
public byte ToByte(Object value) {
if (value==null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ToByte(value, CultureInfo.InvariantCulture);
@@ -74,7 +74,7 @@ namespace System.Runtime.Serialization {
public short ToInt16(Object value) {
if (value==null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ToInt16(value, CultureInfo.InvariantCulture);
@@ -83,7 +83,7 @@ namespace System.Runtime.Serialization {
[CLSCompliant(false)]
public ushort ToUInt16(Object value) {
if (value==null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ToUInt16(value, CultureInfo.InvariantCulture);
@@ -91,7 +91,7 @@ namespace System.Runtime.Serialization {
public int ToInt32(Object value) {
if (value==null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ToInt32(value, CultureInfo.InvariantCulture);
@@ -100,7 +100,7 @@ namespace System.Runtime.Serialization {
[CLSCompliant(false)]
public uint ToUInt32(Object value) {
if (value==null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ToUInt32(value, CultureInfo.InvariantCulture);
@@ -108,7 +108,7 @@ namespace System.Runtime.Serialization {
public long ToInt64(Object value) {
if (value==null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ToInt64(value, CultureInfo.InvariantCulture);
@@ -117,7 +117,7 @@ namespace System.Runtime.Serialization {
[CLSCompliant(false)]
public ulong ToUInt64(Object value) {
if (value==null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ToUInt64(value, CultureInfo.InvariantCulture);
@@ -125,7 +125,7 @@ namespace System.Runtime.Serialization {
public float ToSingle(Object value) {
if (value==null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ToSingle(value, CultureInfo.InvariantCulture);
@@ -133,7 +133,7 @@ namespace System.Runtime.Serialization {
public double ToDouble(Object value) {
if (value==null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ToDouble(value, CultureInfo.InvariantCulture);
@@ -141,7 +141,7 @@ namespace System.Runtime.Serialization {
public Decimal ToDecimal(Object value) {
if (value==null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ToDecimal(value, CultureInfo.InvariantCulture);
@@ -149,7 +149,7 @@ namespace System.Runtime.Serialization {
public DateTime ToDateTime(Object value) {
if (value==null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ToDateTime(value, CultureInfo.InvariantCulture);
@@ -157,7 +157,7 @@ namespace System.Runtime.Serialization {
public String ToString(Object value) {
if (value==null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ToString(value, CultureInfo.InvariantCulture);
diff --git a/src/mscorlib/src/System/Runtime/Serialization/FormatterServices.cs b/src/mscorlib/src/System/Runtime/Serialization/FormatterServices.cs
index c6f27b5b2a..27c3f15136 100644
--- a/src/mscorlib/src/System/Runtime/Serialization/FormatterServices.cs
+++ b/src/mscorlib/src/System/Runtime/Serialization/FormatterServices.cs
@@ -29,16 +29,15 @@ namespace System.Runtime.Serialization {
using System.IO;
using System.Text;
using System.Globalization;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
[System.Runtime.InteropServices.ComVisible(true)]
public static class FormatterServices {
#if FEATURE_SERIALIZATION
internal static Dictionary<MemberHolder, MemberInfo[]> m_MemberInfoTable = new Dictionary<MemberHolder, MemberInfo[]>(32);
- [System.Security.SecurityCritical]
private static bool unsafeTypeForwardersIsEnabled = false;
- [System.Security.SecurityCritical]
private static volatile bool unsafeTypeForwardersIsEnabledInitialized = false;
private static Object s_FormatterServicesSyncObject = null;
@@ -56,7 +55,6 @@ namespace System.Runtime.Serialization {
}
}
- [SecuritySafeCritical]
static FormatterServices()
{
// Static initialization touches security critical types, so we need an
@@ -100,7 +98,7 @@ namespace System.Runtime.Serialization {
FieldInfo [] typeFields;
RuntimeType parentType;
- Contract.Assert((object)type != null, "[GetAllSerializableMembers]type!=null");
+ Debug.Assert((object)type != null, "[GetAllSerializableMembers]type!=null");
if (type.IsInterface) {
return new MemberInfo[0];
@@ -186,7 +184,6 @@ namespace System.Runtime.Serialization {
// be included, properties must have both a getter and a setter. N.B.: A class
// which implements ISerializable or has a serialization surrogate may not use all of these members
// (or may have additional members).
- [System.Security.SecurityCritical] // auto-generated_required
public static MemberInfo[] GetSerializableMembers(Type type) {
return GetSerializableMembers(type, new StreamingContext(StreamingContextStates.All));
}
@@ -194,12 +191,11 @@ namespace System.Runtime.Serialization {
// Get all of the Serializable Members for a particular class. If we're not cloning, this is all
// non-transient, non-static fields. If we are cloning, include the transient fields as well since
// we know that we're going to live inside of the same context.
- [System.Security.SecurityCritical] // auto-generated_required
public static MemberInfo[] GetSerializableMembers(Type type, StreamingContext context) {
MemberInfo[] members;
if ((object)type==null) {
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
}
Contract.EndContractBlock();
@@ -230,14 +226,9 @@ namespace System.Runtime.Serialization {
static readonly Type[] advancedTypes = new Type[]{
typeof(System.DelegateSerializationHolder),
-#if FEATURE_REMOTING
- typeof(System.Runtime.Remoting.ObjRef),
- typeof(System.Runtime.Remoting.IEnvoyInfo),
- typeof(System.Runtime.Remoting.Lifetime.ISponsor),
-#endif
};
-
- public static void CheckTypeSecurity(Type t, TypeFilterLevel securityLevel) {
+
+ public static void CheckTypeSecurity(Type t, TypeFilterLevel securityLevel) {
if (securityLevel == TypeFilterLevel.Low){
for(int i=0;i<advancedTypes.Length;i++){
if (advancedTypes[i].IsAssignableFrom(t))
@@ -254,10 +245,9 @@ namespace System.Runtime.Serialization {
// will not create an unitialized string because it is non-sensical to create an empty
// instance of an immutable type.
//
- [System.Security.SecurityCritical] // auto-generated_required
public static Object GetUninitializedObject(Type type) {
if ((object)type == null) {
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
}
Contract.EndContractBlock();
@@ -268,44 +258,33 @@ namespace System.Runtime.Serialization {
return nativeGetUninitializedObject((RuntimeType)type);
}
- [System.Security.SecurityCritical] // auto-generated_required
public static Object GetSafeUninitializedObject(Type type) {
if ((object)type == null) {
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
}
Contract.EndContractBlock();
-
+
if (!(type is RuntimeType)) {
throw new SerializationException(Environment.GetResourceString("Serialization_InvalidType", type.ToString()));
}
-#if FEATURE_REMOTING
- if (Object.ReferenceEquals(type, typeof(System.Runtime.Remoting.Messaging.ConstructionCall)) ||
- Object.ReferenceEquals(type, typeof(System.Runtime.Remoting.Messaging.LogicalCallContext)) ||
- Object.ReferenceEquals(type, typeof(System.Runtime.Remoting.Contexts.SynchronizationAttribute)))
- return nativeGetUninitializedObject((RuntimeType)type);
-#endif
- try {
- return nativeGetSafeUninitializedObject((RuntimeType)type);
+ try {
+ return nativeGetSafeUninitializedObject((RuntimeType)type);
}
- catch(SecurityException e) {
+ catch(SecurityException e) {
throw new SerializationException(Environment.GetResourceString("Serialization_Security", type.FullName), e);
- }
+ }
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern Object nativeGetSafeUninitializedObject(RuntimeType type);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern Object nativeGetUninitializedObject(RuntimeType type);
#if FEATURE_SERIALIZATION
- [System.Security.SecurityCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern bool GetEnableUnsafeTypeForwarders();
- [SecuritySafeCritical]
internal static bool UnsafeTypeForwardersIsEnabled()
{
if (!unsafeTypeForwardersIsEnabledInitialized)
@@ -318,7 +297,6 @@ namespace System.Runtime.Serialization {
}
#endif
private static Binder s_binder = Type.DefaultBinder;
- [System.Security.SecurityCritical]
internal static void SerializationSetValue(MemberInfo fi, Object target, Object value)
{
Contract.Requires(fi != null);
@@ -345,18 +323,17 @@ namespace System.Runtime.Serialization {
// Fill in the members of obj with the data contained in data.
// Returns the number of members populated.
//
- [System.Security.SecurityCritical] // auto-generated_required
public static Object PopulateObjectMembers(Object obj, MemberInfo[] members, Object[] data) {
if (obj==null) {
- throw new ArgumentNullException("obj");
+ throw new ArgumentNullException(nameof(obj));
}
if (members==null) {
- throw new ArgumentNullException("members");
+ throw new ArgumentNullException(nameof(members));
}
if (data==null) {
- throw new ArgumentNullException("data");
+ throw new ArgumentNullException(nameof(data));
}
if (members.Length!=data.Length) {
@@ -372,7 +349,7 @@ namespace System.Runtime.Serialization {
mi = members[i];
if (mi==null) {
- throw new ArgumentNullException("members", Environment.GetResourceString("ArgumentNull_NullMember", i));
+ throw new ArgumentNullException(nameof(members), Environment.GetResourceString("ArgumentNull_NullMember", i));
}
//If we find an empty, it means that the value was never set during deserialization.
@@ -400,15 +377,14 @@ namespace System.Runtime.Serialization {
// extract (must be FieldInfos or PropertyInfos). For each supplied member, extract the matching value and
// return it in a Object[] of the same size.
//
- [System.Security.SecurityCritical] // auto-generated_required
public static Object[] GetObjectData(Object obj, MemberInfo[] members) {
if (obj==null) {
- throw new ArgumentNullException("obj");
+ throw new ArgumentNullException(nameof(obj));
}
if (members==null) {
- throw new ArgumentNullException("members");
+ throw new ArgumentNullException(nameof(members));
}
Contract.EndContractBlock();
@@ -421,11 +397,11 @@ namespace System.Runtime.Serialization {
mi=members[i];
if (mi==null) {
- throw new ArgumentNullException("members", Environment.GetResourceString("ArgumentNull_NullMember", i));
+ throw new ArgumentNullException(nameof(members), Environment.GetResourceString("ArgumentNull_NullMember", i));
}
if (mi.MemberType==MemberTypes.Field) {
- Contract.Assert(mi is RuntimeFieldInfo || mi is SerializationFieldInfo,
+ Debug.Assert(mi is RuntimeFieldInfo || mi is SerializationFieldInfo,
"[FormatterServices.GetObjectData]mi is RuntimeFieldInfo || mi is SerializationFieldInfo.");
RtFieldInfo rfi = mi as RtFieldInfo;
@@ -443,12 +419,11 @@ namespace System.Runtime.Serialization {
return data;
}
- [System.Security.SecurityCritical] // auto-generated_required
[System.Runtime.InteropServices.ComVisible(false)]
public static ISerializationSurrogate GetSurrogateForCyclicalReference(ISerializationSurrogate innerSurrogate)
{
if (innerSurrogate == null)
- throw new ArgumentNullException("innerSurrogate");
+ throw new ArgumentNullException(nameof(innerSurrogate));
Contract.EndContractBlock();
return new SurrogateForCyclicalReference(innerSurrogate);
}
@@ -459,10 +434,9 @@ namespace System.Runtime.Serialization {
**Arguments:
**Exceptions:
==============================================================================*/
- [System.Security.SecurityCritical] // auto-generated_required
public static Type GetTypeFromAssembly(Assembly assem, String name) {
if (assem==null)
- throw new ArgumentNullException("assem");
+ throw new ArgumentNullException(nameof(assem));
Contract.EndContractBlock();
return assem.GetType(name, false, false);
}
@@ -499,7 +473,7 @@ namespace System.Runtime.Serialization {
internal static string GetClrAssemblyName(Type type, out bool hasTypeForwardedFrom) {
if ((object)type == null) {
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
}
object[] typeAttributes = type.GetCustomAttributes(typeof(TypeForwardedFromAttribute), false);
@@ -566,17 +540,15 @@ namespace System.Runtime.Serialization {
internal SurrogateForCyclicalReference(ISerializationSurrogate innerSurrogate)
{
if (innerSurrogate == null)
- throw new ArgumentNullException("innerSurrogate");
+ throw new ArgumentNullException(nameof(innerSurrogate));
this.innerSurrogate = innerSurrogate;
}
- [System.Security.SecurityCritical] // auto-generated
public void GetObjectData(Object obj, SerializationInfo info, StreamingContext context)
{
innerSurrogate.GetObjectData(obj, info, context);
}
- [System.Security.SecurityCritical] // auto-generated
public Object SetObjectData(Object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector)
{
return innerSurrogate.SetObjectData(obj, info, context, selector);
diff --git a/src/mscorlib/src/System/Runtime/Serialization/IObjectReference.cs b/src/mscorlib/src/System/Runtime/Serialization/IObjectReference.cs
index f1a1bc0590..42662a10f6 100644
--- a/src/mscorlib/src/System/Runtime/Serialization/IObjectReference.cs
+++ b/src/mscorlib/src/System/Runtime/Serialization/IObjectReference.cs
@@ -22,7 +22,6 @@ namespace System.Runtime.Serialization {
// Interface does not need to be marked with the serializable attribute
[System.Runtime.InteropServices.ComVisible(true)]
public interface IObjectReference {
- [System.Security.SecurityCritical] // auto-generated_required
Object GetRealObject(StreamingContext context);
}
}
diff --git a/src/mscorlib/src/System/Runtime/Serialization/ISerializable.cs b/src/mscorlib/src/System/Runtime/Serialization/ISerializable.cs
index e59fa65043..fc283d41f1 100644
--- a/src/mscorlib/src/System/Runtime/Serialization/ISerializable.cs
+++ b/src/mscorlib/src/System/Runtime/Serialization/ISerializable.cs
@@ -22,7 +22,6 @@ namespace System.Runtime.Serialization {
[System.Runtime.InteropServices.ComVisible(true)]
public interface ISerializable {
- [System.Security.SecurityCritical] // auto-generated_required
void GetObjectData(SerializationInfo info, StreamingContext context);
}
diff --git a/src/mscorlib/src/System/Runtime/Serialization/ISerializationSurrogate.cs b/src/mscorlib/src/System/Runtime/Serialization/ISerializationSurrogate.cs
index 9bb30d99e0..226bbdcc75 100644
--- a/src/mscorlib/src/System/Runtime/Serialization/ISerializationSurrogate.cs
+++ b/src/mscorlib/src/System/Runtime/Serialization/ISerializationSurrogate.cs
@@ -24,13 +24,11 @@ namespace System.Runtime.Serialization {
// Returns a SerializationInfo completely populated with all of the data needed to reinstantiate the
// the object at the other end of serialization.
//
- [System.Security.SecurityCritical] // auto-generated_required
void GetObjectData(Object obj, SerializationInfo info, StreamingContext context);
// Reinflate the object using all of the information in data. The information in
// members is used to find the particular field or property which needs to be set.
//
- [System.Security.SecurityCritical] // auto-generated_required
Object SetObjectData(Object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector);
}
}
diff --git a/src/mscorlib/src/System/Runtime/Serialization/ISurrogateSelector.cs b/src/mscorlib/src/System/Runtime/Serialization/ISurrogateSelector.cs
index 01b960f86b..87b7845894 100644
--- a/src/mscorlib/src/System/Runtime/Serialization/ISurrogateSelector.cs
+++ b/src/mscorlib/src/System/Runtime/Serialization/ISurrogateSelector.cs
@@ -22,16 +22,13 @@ namespace System.Runtime.Serialization {
// Interface does not need to be marked with the serializable attribute
// Specifies the next ISurrogateSelector to be examined for surrogates if the current
// instance doesn't have a surrogate for the given type and assembly in the given context.
- [System.Security.SecurityCritical] // auto-generated_required
void ChainSelector(ISurrogateSelector selector);
// Returns the appropriate surrogate for the given type in the given context.
- [System.Security.SecurityCritical] // auto-generated_required
ISerializationSurrogate GetSurrogate(Type type, StreamingContext context, out ISurrogateSelector selector);
// Return the next surrogate in the chain. Returns null if no more exist.
- [System.Security.SecurityCritical] // auto-generated_required
ISurrogateSelector GetNextSelector();
}
}
diff --git a/src/mscorlib/src/System/Runtime/Serialization/SafeSerializationManager.cs b/src/mscorlib/src/System/Runtime/Serialization/SafeSerializationManager.cs
new file mode 100644
index 0000000000..585d367605
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/Serialization/SafeSerializationManager.cs
@@ -0,0 +1,446 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics.Contracts;
+using System.Reflection;
+using System.Security;
+
+namespace System.Runtime.Serialization
+{
+ //
+ // #SafeSerialization
+ //
+ // Types which are serializable via the ISerializable interface have a problem when it comes to allowing
+ // transparent subtypes which can allow themselves to serialize since the GetObjectData method is
+ // SecurityCritical.
+ //
+ // For instance, System.Exception implements ISerializable, however it is also desirable to have
+ // transparent exceptions with their own fields that need to be serialized. (For instance, in transparent
+ // assemblies such as the DLR and F#, or even in partial trust application code). Since overriding
+ // GetObjectData requires that the overriding method be security critical, this won't work directly.
+ //
+ // SafeSerializationManager solves this problem by allowing any partial trust code to contribute
+ // individual chunks of serializable data to be included in the serialized version of the derived class.
+ // These chunks are then deserialized back out of the serialized type and notified that they should
+ // populate the fields of the deserialized object when serialization is complete. This allows partial
+ // trust or transparent code to participate in serialization of an ISerializable type without having to
+ // override GetObjectData or implement the ISerializable constructor.
+ //
+ // On the serialization side, SafeSerializationManager has an event SerializeObjectState which it will
+ // fire in response to serialization in order to gather the units of serializable data that should be
+ // stored with the rest of the object during serialization. Methods which respond to these events
+ // create serializable objects which implement the ISafeSerializationData interface and add them to the
+ // collection of other serialized data by calling AddSerializedState on the SafeSerializationEventArgs
+ // passed into the event.
+ //
+ // By using an event rather than a virtual method on the base ISerializable object, we allow multiple
+ // potentially untrusted subclasses to participate in serialization, without each one having to ensure
+ // that it calls up to the base type in order for the whole system to work. (For instance Exception :
+ // TrustedException : UntrustedException, in this scenario UntrustedException would be able to override
+ // the virtual method an prevent TrustedException from ever seeing the method call, either accidentally
+ // or maliciously).
+ //
+ // Further, by only allowing additions of new chunks of serialization state rather than exposing the
+ // whole underlying list, we avoid exposing potentially sensitive serialized state to any of the
+ // potentially untrusted subclasses.
+ //
+ // At deserialization time, SafeSerializationManager performs the reverse operation. It deserializes the
+ // chunks of serialized state, and then notifies them that the object they belong to is deserialized by
+ // calling their CompleteSerialization method. In repsonse to this call, the state objects populate the
+ // fields of the object being deserialized with the state that they held.
+ //
+ // From a security perspective, the chunks of serialized state can only contain data that the specific
+ // subclass itself had access to read (otherwise it wouldn't be able to populate the type with that
+ // data), as opposed to having access to far more data in the SerializationInfo that GetObjectData uses.
+ // Similarly, at deserialization time, the serialized state can only modify fields that the type itself
+ // has access to (again, as opposed to the full SerializationInfo which could be modified).
+ //
+ // Individual types which wish to participate in safe serialization do so by containing an instance of a
+ // SafeSerializationManager and exposing its serialization event. During GetObjectData, the
+ // SafeSerializationManager is serialized just like any other field of the containing type. However, at
+ // the end of serialization it is called back one last time to CompleteSerialization.
+ //
+ // In CompleteSerialization, if the SafeSerializationManager detects that it has extra chunks of
+ // data to handle, it substitutes the root type being serialized (formerly the real type hosting the
+ // SafeSerializationManager) with itself. This allows it to gain more control over the deserialization
+ // process. It also saves away an extra bit of state in the serialization info indicating the real type
+ // of object that should be recreated during deserialization.
+ //
+ // At this point the serialized state looks like this:
+ // Data:
+ // realSerializedData1
+ // ...
+ // realSerializedDataN
+ // safeSerializationData -> this is the serialization data member of the parent type
+ // m_serializedState -> list of saved serialized states from subclasses responding to the safe
+ // serialization event
+ // RealTypeSerializationName -> type which is using safe serialization
+ // Type:
+ // SafeSerializationManager
+ //
+ // That is, the serialized data claims to be of type SafeSerializationManager, however contains only the
+ // data from the real object being serialized along with one bit of safe serialization metadata.
+ //
+ // At deserialization time, since the serialized data claims to be of type SafeSerializationManager, the
+ // root object being created is an instance of the SafeSerializationManager class. However, it detects
+ // that this isn't a real SafeSerializationManager (by looking for the real type field in the metadata),
+ // and simply saves away the SerializationInfo and the real type being deserialized.
+ //
+ // Since SafeSerializationManager implements IObjectReference, the next step of deserialization is the
+ // GetRealObject callback. This callback is the one responsible for getting the
+ // SafeSerializationManager out of the way and instead creating an instance of the actual type which was
+ // serialized.
+ //
+ // It does this by first creating an instance of the real type being deserialzed (saved away in the
+ // deserialzation constructor), but not running any of its constructors. Instead, it walks the
+ // inheritance hierarchy (moving toward the most derived type) looking for the last full trust type to
+ // implement the standard ISerializable constructor before any type does not implement the constructor.
+ // It is this last type's deserialization constructor which is then invoked, passing in the saved
+ // SerializationInfo. Once the constructors are run, we return this object as the real deserialized
+ // object.
+ //
+ // The reason that we do this walk is so that ISerializable types can protect themselves from malicious
+ // input during deserialization by making their deserialization constructors unavailable to partial
+ // trust code. By not requiring every type have a copy of this constructor, partial trust code can
+ // participate in safe serialization and not be required to have access to the parent's constructor.
+ //
+ // It should be noted however, that this heuristic means that if a full trust type does derive from
+ // a transparent or partial trust type using this safe serialization mechanism, that full trust type
+ // will not have its constructor called. Further, the protection of not invoking partial trust
+ // deserialization constructors only comes into play if SafeSerializationManager is in control of
+ // deserialization, which means there must be at least one (even empty) safe serialization event
+ // handler registered.
+ //
+ // Another interesting note is that at this point there are now two SafeSerializationManagers alive for
+ // this deserialization. The first object is the one which is controlling the deserialization and was
+ // created as the root object of the deserialization. The second one is the object which contains the
+ // serialized data chunks and is a data member of the real object being deserialized. For this reason,
+ // the data objects cannot be notified that the deserialization is complete during GetRealObject since
+ // the ISafeSerializationData objects are not members of the active SafeSerializationManager instance.
+ //
+ // The next step is the OnDeserialized callback, which comes to SafeSerializableObject since it was
+ // pretending to be the root object of the deserialization. It responds to this callback by calling
+ // any existing OnDeserialized callback on the real type that was deserialized.
+ //
+ // The real type needs to call its data member SafeSerializationData object's CompleteDeserialization
+ // method in response to the OnDeserialized call. This CompleteDeserialization call will then iterate
+ // through the ISafeSerializationData objects calling each of their CompleteDeserialization methods so
+ // that they can plug the nearly-complete object with their saved data.
+ //
+ // The reason for having a new ISafeSerializationData interface which is basically identical to
+ // IDeserializationCallback is that IDeserializationCallback will be called on the stored data chunks
+ // by the serialization code when they are deserialized, and that's not a desirable behavior.
+ // Essentially, we need to change the meaning of the object parameter to mean "parent object which
+ // participated in safe serialization", rather than "this object".
+ //
+ // Implementing safe serialization on an ISerialiable type is relatively straight forward. (For an
+ // example, see System.Exception):
+ //
+ // 1. Include a data member of type SafeSerializationManager:
+ //
+ // private SafeSerializationManager m_safeSerializationManager;
+ //
+ // 2. Add a protected SerializeObjectState event, which passes through to the SafeSerializationManager:
+ //
+ // protected event EventHandler<SafeSerializationEventArgs> SerializeObjectState
+ // {
+ // add { m_safeSerializationManager.SerializeObjectState += value; }
+ // remove { m_safeSerializationManager.SerializeObjectState -= value; }
+ // }
+ //
+ // 3. Serialize the safe serialization object in GetObjectData, and call its CompleteSerialization method:
+ //
+ // {
+ // info.AddValue("m_safeSerializationManager", m_safeSerializationManager, typeof(SafeSerializationManager));
+ // m_safeSerializationManager.CompleteSerialization(this, info, context);
+ // }
+ //
+ // 4. Add an OnDeserialized handler if one doesn't already exist, and call CompleteDeserialization in it:
+ //
+ // [OnDeserialized]
+ // private void OnDeserialized(StreamingContext context)
+ // {
+ // m_safeSerializationManager.CompleteDeserialization(this);
+ // }
+ //
+ // On the client side, using safe serialization is also pretty easy. For example:
+ //
+ // [Serializable]
+ // public class TransparentException : Exception
+ // {
+ // [Serializable]
+ // private struct TransparentExceptionState : ISafeSerializationData
+ // {
+ // public string m_extraData;
+ //
+ // void ISafeSerializationData.CompleteDeserialization(object obj)
+ // {
+ // TransparentException exception = obj as TransparentException;
+ // exception.m_state = this;
+ // }
+ // }
+ //
+ // [NonSerialized]
+ // private TransparentExceptionState m_state = new TransparentExceptionState();
+ //
+ // public TransparentException()
+ // {
+ // SerializeObjectState += delegate(object exception, SafeSerializationEventArgs eventArgs)
+ // {
+ // eventArgs.AddSerializedState(m_state);
+ // };
+ // }
+ //
+ // public string ExtraData
+ // {
+ // get { return m_state.m_extraData; }
+ // set { m_state.m_extraData = value; }
+ // }
+ // }
+ //
+
+ // SafeSerializationEventArgs are provided to the delegates which do safe serialization. Each delegate
+ // serializes its own state into an IDeserializationCallback instance which must, itself, be serializable.
+ // These indivdiual states are then added to the SafeSerializationEventArgs in order to be saved away when
+ // the original ISerializable type is serialized.
+ public sealed class SafeSerializationEventArgs : EventArgs
+ {
+ private StreamingContext m_streamingContext;
+ private List<object> m_serializedStates = new List<object>();
+
+ internal SafeSerializationEventArgs(StreamingContext streamingContext)
+ {
+ m_streamingContext = streamingContext;
+ }
+
+ public void AddSerializedState(ISafeSerializationData serializedState)
+ {
+ if (serializedState == null)
+ throw new ArgumentNullException(nameof(serializedState));
+ if (!serializedState.GetType().IsSerializable)
+ throw new ArgumentException(Environment.GetResourceString("Serialization_NonSerType", serializedState.GetType(), serializedState.GetType().Assembly.FullName));
+
+ m_serializedStates.Add(serializedState);
+ }
+
+ internal IList<object> SerializedStates
+ {
+ get { return m_serializedStates; }
+ }
+
+ public StreamingContext StreamingContext
+ {
+ get { return m_streamingContext; }
+ }
+ }
+
+ // Interface to be supported by objects which are stored in safe serialization stores
+ public interface ISafeSerializationData
+ {
+ // CompleteDeserialization is called when the object to which the extra serialized data was attached
+ // has completed its deserialization, and now needs to be populated with the extra data stored in
+ // this object.
+ void CompleteDeserialization(object deserialized);
+ }
+#if FEATURE_SERIALIZATION
+ // Helper class to implement safe serialization. Concrete ISerializable types which want to allow
+ // transparent subclasses code to participate in serialization should contain an instance of
+ // SafeSerializationManager and wire up to it as described in code:#SafeSerialization.
+ [Serializable]
+ internal sealed class SafeSerializationManager : IObjectReference, ISerializable
+ {
+ // Saved states to store in the serialization stream. This is typed as object rather than
+ // ISafeSerializationData because ISafeSerializationData can't be marked serializable.
+ private IList<object> m_serializedStates;
+
+ // This is the SerializationInfo that is used when the SafeSerializationManager type has replaced
+ // itself as the target of serialziation. It is not used directly by the safe serialization code,
+ // but just held onto so that the real object being deserialzed can use it later.
+ private SerializationInfo m_savedSerializationInfo;
+
+ // Real object that we've deserialized - this is stored when we complete construction and calling
+ // the deserialization .ctors on it and is used when we need to notify the stored safe
+ // deserialization data that they should populate the object with their fields.
+ private object m_realObject;
+
+ // Real type that should be deserialized
+ private RuntimeType m_realType;
+
+ // Event fired when we need to collect state to serialize into the parent object
+ internal event EventHandler<SafeSerializationEventArgs> SerializeObjectState;
+
+ // Name that is used to store the real type being deserialized in the main SerializationInfo
+ private const string RealTypeSerializationName = "CLR_SafeSerializationManager_RealType";
+
+ internal SafeSerializationManager()
+ {
+ }
+
+ private SafeSerializationManager(SerializationInfo info, StreamingContext context)
+ {
+ // We need to determine if we're being called to really deserialize a SafeSerializationManager,
+ // or if we're being called because we've intercepted the deserialization callback for the real
+ // object being deserialized. We use the presence of the RealTypeSerializationName field in the
+ // serialization info to indicate that this is the interception callback and we just need to
+ // safe the info. If that field is not present, then we should be in a real deserialization
+ // construction.
+ RuntimeType realType = info.GetValueNoThrow(RealTypeSerializationName, typeof(RuntimeType)) as RuntimeType;
+
+ if (realType == null)
+ {
+ m_serializedStates = info.GetValue("m_serializedStates", typeof(List<object>)) as List<object>;
+ }
+ else
+ {
+ m_realType = realType;
+ m_savedSerializationInfo = info;
+ }
+ }
+
+ // Determine if the serialization manager is in an active state - that is if any code is hooked up
+ // to use it for serialization
+ internal bool IsActive
+ {
+ get { return SerializeObjectState != null; }
+ }
+
+ // CompleteSerialization is called by the base ISerializable in its GetObjectData method. It is
+ // responsible for gathering up the serialized object state of any delegates that wish to add their
+ // own state to the serialized object.
+ internal void CompleteSerialization(object serializedObject,
+ SerializationInfo info,
+ StreamingContext context)
+ {
+ Contract.Requires(serializedObject != null);
+ Contract.Requires(info != null);
+ Contract.Requires(typeof(ISerializable).IsAssignableFrom(serializedObject.GetType()));
+ Contract.Requires(serializedObject.GetType().IsAssignableFrom(info.ObjectType));
+
+ // Clear out any stale state
+ m_serializedStates = null;
+
+ // We only want to kick in our special serialization sauce if someone wants to participate in
+ // it, otherwise if we have no delegates registered there's no reason for us to get in the way
+ // of the regular serialization machinery.
+ EventHandler<SafeSerializationEventArgs> serializeObjectStateEvent = SerializeObjectState;
+ if (serializeObjectStateEvent != null)
+ {
+ // Get any extra data to add to our serialization state now
+ SafeSerializationEventArgs eventArgs = new SafeSerializationEventArgs(context);
+ serializeObjectStateEvent(serializedObject, eventArgs);
+ m_serializedStates = eventArgs.SerializedStates;
+
+ // Replace the type to be deserialized by the standard serialization code paths with
+ // ourselves, which allows us to control the deserialization process.
+ info.AddValue(RealTypeSerializationName, serializedObject.GetType(), typeof(RuntimeType));
+ info.SetType(typeof(SafeSerializationManager));
+ }
+ }
+
+ // CompleteDeserialization is called by the base ISerializable object's OnDeserialized handler to
+ // finish the deserialization of the object by notifying the saved states that they should
+ // re-populate their portions of the deserialized object.
+ internal void CompleteDeserialization(object deserializedObject)
+ {
+ Contract.Requires(deserializedObject != null);
+
+ if (m_serializedStates != null)
+ {
+ foreach (ISafeSerializationData serializedState in m_serializedStates)
+ {
+ serializedState.CompleteDeserialization(deserializedObject);
+ }
+ }
+ }
+
+ void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ info.AddValue("m_serializedStates", m_serializedStates, typeof(List<IDeserializationCallback>));
+ }
+
+ // GetRealObject intercepts the deserialization process in order to allow deserializing part of the
+ // object's inheritance heirarchy using standard ISerializable constructors, and the remaining
+ // portion using the saved serialization states.
+ object IObjectReference.GetRealObject(StreamingContext context)
+ {
+ // If we've already deserialized the real object, use that rather than deserializing it again
+ if (m_realObject != null)
+ {
+ return m_realObject;
+ }
+
+ // If we don't have a real type to deserialize, then this is really a SafeSerializationManager
+ // and we don't need to rebuild the object that we're standing in for.
+ if (m_realType == null)
+ {
+ return this;
+ }
+
+ // Look for the last type in GetRealType's inheritance hierarchy which implements a critical
+ // deserialization constructor. This will be the object that we use as the deserialization
+ // construction type to initialize via standard ISerializable semantics
+
+ // First build up the chain starting at the type below Object and working to the real type we
+ // serialized.
+ Stack inheritanceChain = new Stack();
+ RuntimeType currentType = m_realType;
+ do
+ {
+ inheritanceChain.Push(currentType);
+ currentType = currentType.BaseType as RuntimeType;
+ }
+ while (currentType != typeof(object));
+
+ // Now look for the first type that does not implement the ISerializable .ctor. When we find
+ // that, previousType will point at the last type that did implement the .ctor. We require that
+ // the .ctor we invoke also be non-transparent
+ RuntimeConstructorInfo serializationCtor = null;
+ RuntimeType previousType = null;
+ do
+ {
+ previousType = currentType;
+ currentType = inheritanceChain.Pop() as RuntimeType;
+ serializationCtor = currentType.GetSerializationCtor();
+ }
+ while (serializationCtor != null && serializationCtor.IsSecurityCritical);
+
+ // previousType is the last type that did implement the deserialization .ctor before the first
+ // type that did not, so we'll grab it's .ctor to use for deserialization.
+ BCLDebug.Assert(previousType != null, "We should have at least one inheritance from the base type");
+ serializationCtor = ObjectManager.GetConstructor(previousType);
+
+ // Allocate an instance of the final type and run the selected .ctor on that instance to get the
+ // standard ISerializable initialization done.
+ object deserialized = FormatterServices.GetUninitializedObject(m_realType);
+ serializationCtor.SerializationInvoke(deserialized, m_savedSerializationInfo, context);
+ m_savedSerializationInfo = null;
+ m_realType = null;
+
+ // Save away the real object that was deserialized so that we can fill it in later, and return
+ // it back as the object that should result from the final deserialization.
+ m_realObject = deserialized;
+ return deserialized;
+ }
+
+ [OnDeserialized]
+ private void OnDeserialized(StreamingContext context)
+ {
+ // We only need to complete deserialization if we were hooking the deserialization process. If
+ // we have not deserialized an object in the GetRealObject call, then there's nothing more for
+ // us to do here.
+ if (m_realObject != null)
+ {
+ // Fire the real object's OnDeserialized method if they registered one. Since we replaced
+ // ourselves as the target of the deserialization, OnDeserialized on the target won't
+ // automatically get triggered unless we do it manually.
+ SerializationEvents cache = SerializationEventsCache.GetSerializationEventsForType(m_realObject.GetType());
+ cache.InvokeOnDeserialized(m_realObject, context);
+ m_realObject = null;
+ }
+ }
+ }
+#endif
+}
diff --git a/src/mscorlib/src/System/Runtime/Serialization/SerializationFieldInfo.cs b/src/mscorlib/src/System/Runtime/Serialization/SerializationFieldInfo.cs
index 5e7851bc57..82536ce3b4 100644
--- a/src/mscorlib/src/System/Runtime/Serialization/SerializationFieldInfo.cs
+++ b/src/mscorlib/src/System/Runtime/Serialization/SerializationFieldInfo.cs
@@ -21,11 +21,9 @@ namespace System.Runtime.Serialization {
using System;
using System.Reflection;
using System.Globalization;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Threading;
-#if FEATURE_REMOTING
- using System.Runtime.Remoting.Metadata;
-#endif //FEATURE_REMOTING
internal sealed class SerializationFieldInfo : FieldInfo {
@@ -38,8 +36,8 @@ namespace System.Runtime.Serialization {
public override int MetadataToken { get { return m_field.MetadataToken; } }
internal SerializationFieldInfo(RuntimeFieldInfo field, String namePrefix) {
- Contract.Assert(field!=null, "[SerializationFieldInfo.ctor]field!=null");
- Contract.Assert(namePrefix!=null, "[SerializationFieldInfo.ctor]namePrefix!=null");
+ Debug.Assert(field!=null, "[SerializationFieldInfo.ctor]field!=null");
+ Debug.Assert(namePrefix!=null, "[SerializationFieldInfo.ctor]namePrefix!=null");
m_field = field;
m_serializationName = String.Concat(namePrefix, FakeNameSeparatorString, m_field.Name);
@@ -91,7 +89,6 @@ namespace System.Runtime.Serialization {
return m_field.GetValue(obj);
}
- [System.Security.SecurityCritical]
internal Object InternalGetValue(Object obj) {
RtFieldInfo field = m_field as RtFieldInfo;
if (field != null)
@@ -107,7 +104,6 @@ namespace System.Runtime.Serialization {
m_field.SetValue(obj, value, invokeAttr, binder, culture);
}
- [System.Security.SecurityCritical]
internal void InternalSetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture) {
RtFieldInfo field = m_field as RtFieldInfo;
if (field != null)
@@ -136,31 +132,5 @@ namespace System.Runtime.Serialization {
return m_field.Attributes;
}
}
-
-#if FEATURE_REMOTING
- #region Legacy Remoting Cache
- private RemotingFieldCachedData m_cachedData;
-
- internal RemotingFieldCachedData RemotingCache
- {
- get
- {
- // This grabs an internal copy of m_cachedData and uses
- // that instead of looking at m_cachedData directly because
- // the cache may get cleared asynchronously. This prevents
- // us from having to take a lock.
- RemotingFieldCachedData cache = m_cachedData;
- if (cache == null)
- {
- cache = new RemotingFieldCachedData(this);
- RemotingFieldCachedData ret = Interlocked.CompareExchange(ref m_cachedData, cache, null);
- if (ret != null)
- cache = ret;
- }
- return cache;
- }
- }
- #endregion
-#endif //FEATURE_REMOTING
}
}
diff --git a/src/mscorlib/src/System/Runtime/Serialization/SerializationInfo.cs b/src/mscorlib/src/System/Runtime/Serialization/SerializationInfo.cs
index 94e6825b51..55909c85fd 100644
--- a/src/mscorlib/src/System/Runtime/Serialization/SerializationInfo.cs
+++ b/src/mscorlib/src/System/Runtime/Serialization/SerializationInfo.cs
@@ -18,15 +18,11 @@ namespace System.Runtime.Serialization
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.Remoting;
-#if FEATURE_REMOTING
- using System.Runtime.Remoting.Proxies;
-#endif
using System.Globalization;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Security;
-#if FEATURE_CORECLR
using System.Runtime.CompilerServices;
-#endif
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class SerializationInfo
@@ -61,12 +57,12 @@ namespace System.Runtime.Serialization
{
if ((object)type == null)
{
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
}
if (converter == null)
{
- throw new ArgumentNullException("converter");
+ throw new ArgumentNullException(nameof(converter));
}
Contract.EndContractBlock();
@@ -96,7 +92,7 @@ namespace System.Runtime.Serialization
{
if (null == value)
{
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
@@ -111,12 +107,11 @@ namespace System.Runtime.Serialization
{
return m_assemName;
}
- [SecuritySafeCritical]
set
{
if (null == value)
{
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
if (this.requireSameTokenInPartialTrust)
@@ -128,12 +123,11 @@ namespace System.Runtime.Serialization
}
}
- [SecuritySafeCritical]
public void SetType(Type type)
{
if ((object)type == null)
{
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
}
Contract.EndContractBlock();
@@ -170,15 +164,8 @@ namespace System.Runtime.Serialization
}
}
- [SecuritySafeCritical]
internal static void DemandForUnsafeAssemblyNameAssignments(string originalAssemblyName, string newAssemblyName)
{
-#if !FEATURE_CORECLR
- if (!IsAssemblyNameAssignmentSafe(originalAssemblyName, newAssemblyName))
- {
- CodeAccessPermission.Demand(PermissionType.SecuritySerialization);
- }
-#endif
}
internal static bool IsAssemblyNameAssignmentSafe(string originalAssemblyName, string newAssemblyName)
@@ -242,7 +229,7 @@ namespace System.Runtime.Serialization
private void ExpandArrays()
{
int newSize;
- Contract.Assert(m_members.Length == m_currMember, "[SerializationInfo.ExpandArrays]m_members.Length == m_currMember");
+ Debug.Assert(m_members.Length == m_currMember, "[SerializationInfo.ExpandArrays]m_members.Length == m_currMember");
newSize = (m_currMember * 2);
@@ -280,12 +267,12 @@ namespace System.Runtime.Serialization
{
if (null == name)
{
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
}
if ((object)type == null)
{
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
}
Contract.EndContractBlock();
@@ -416,19 +403,14 @@ namespace System.Runtime.Serialization
**Exceptions: None. All error checking is done with asserts. Although public in coreclr,
** it's not exposed in a contract and is only meant to be used by corefx.
==============================================================================*/
-#if FEATURE_CORECLR
// This should not be used by clients: exposing out this functionality would allow children
// to overwrite their parent's values. It is public in order to give corefx access to it for
// its ObjectManager implementation, but it should not be exposed out of a contract.
- public
-#else
- internal
-#endif
- void UpdateValue(String name, Object value, Type type)
+ public void UpdateValue(String name, Object value, Type type)
{
- Contract.Assert(null != name, "[SerializationInfo.UpdateValue]name!=null");
- Contract.Assert(null != value, "[SerializationInfo.UpdateValue]value!=null");
- Contract.Assert(null != (object)type, "[SerializationInfo.UpdateValue]type!=null");
+ Debug.Assert(null != name, "[SerializationInfo.UpdateValue]name!=null");
+ Debug.Assert(null != value, "[SerializationInfo.UpdateValue]value!=null");
+ Debug.Assert(null != (object)type, "[SerializationInfo.UpdateValue]type!=null");
int index = FindElement(name);
if (index < 0)
@@ -447,7 +429,7 @@ namespace System.Runtime.Serialization
{
if (null == name)
{
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
}
Contract.EndContractBlock();
BCLDebug.Trace("SER", "[SerializationInfo.FindElement]Looking for ", name, " CurrMember is: ", m_currMember);
@@ -477,11 +459,11 @@ namespace System.Runtime.Serialization
throw new SerializationException(Environment.GetResourceString("Serialization_NotFound", name));
}
- Contract.Assert(index < m_data.Length, "[SerializationInfo.GetElement]index<m_data.Length");
- Contract.Assert(index < m_types.Length, "[SerializationInfo.GetElement]index<m_types.Length");
+ Debug.Assert(index < m_data.Length, "[SerializationInfo.GetElement]index<m_data.Length");
+ Debug.Assert(index < m_types.Length, "[SerializationInfo.GetElement]index<m_types.Length");
foundType = m_types[index];
- Contract.Assert((object)foundType != null, "[SerializationInfo.GetElement]foundType!=null");
+ Debug.Assert((object)foundType != null, "[SerializationInfo.GetElement]foundType!=null");
return m_data[index];
}
@@ -495,11 +477,11 @@ namespace System.Runtime.Serialization
return null;
}
- Contract.Assert(index < m_data.Length, "[SerializationInfo.GetElement]index<m_data.Length");
- Contract.Assert(index < m_types.Length, "[SerializationInfo.GetElement]index<m_types.Length");
+ Debug.Assert(index < m_data.Length, "[SerializationInfo.GetElement]index<m_data.Length");
+ Debug.Assert(index < m_types.Length, "[SerializationInfo.GetElement]index<m_types.Length");
foundType = m_types[index];
- Contract.Assert((object)foundType != null, "[SerializationInfo.GetElement]foundType!=null");
+ Debug.Assert((object)foundType != null, "[SerializationInfo.GetElement]foundType!=null");
return m_data[index];
}
@@ -508,13 +490,12 @@ namespace System.Runtime.Serialization
// form requested.
//
- [System.Security.SecuritySafeCritical] // auto-generated
public Object GetValue(String name, Type type)
{
if ((object)type == null)
{
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
}
Contract.EndContractBlock();
@@ -526,53 +507,36 @@ namespace System.Runtime.Serialization
Object value;
value = GetElement(name, out foundType);
-#if FEATURE_REMOTING
- if (RemotingServices.IsTransparentProxy(value))
+
+ if (Object.ReferenceEquals(foundType, type) || type.IsAssignableFrom(foundType) || value == null)
{
- RealProxy proxy = RemotingServices.GetRealProxy(value);
- if (RemotingServices.ProxyCheckCast(proxy, rt))
- return value;
+ return value;
}
- else
-#endif
- if (Object.ReferenceEquals(foundType, type) || type.IsAssignableFrom(foundType) || value == null)
- {
- return value;
- }
- Contract.Assert(m_converter != null, "[SerializationInfo.GetValue]m_converter!=null");
+ Debug.Assert(m_converter != null, "[SerializationInfo.GetValue]m_converter!=null");
return m_converter.Convert(value, type);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.InteropServices.ComVisible(true)]
internal Object GetValueNoThrow(String name, Type type)
{
Type foundType;
Object value;
- Contract.Assert((object)type != null, "[SerializationInfo.GetValue]type ==null");
- Contract.Assert(type is RuntimeType, "[SerializationInfo.GetValue]type is not a runtime type");
+ Debug.Assert((object)type != null, "[SerializationInfo.GetValue]type ==null");
+ Debug.Assert(type is RuntimeType, "[SerializationInfo.GetValue]type is not a runtime type");
value = GetElementNoThrow(name, out foundType);
if (value == null)
return null;
-#if FEATURE_REMOTING
- if (RemotingServices.IsTransparentProxy(value))
+
+ if (Object.ReferenceEquals(foundType, type) || type.IsAssignableFrom(foundType) || value == null)
{
- RealProxy proxy = RemotingServices.GetRealProxy(value);
- if (RemotingServices.ProxyCheckCast(proxy, (RuntimeType)type))
- return value;
+ return value;
}
- else
-#endif
- if (Object.ReferenceEquals(foundType, type) || type.IsAssignableFrom(foundType) || value == null)
- {
- return value;
- }
- Contract.Assert(m_converter != null, "[SerializationInfo.GetValue]m_converter!=null");
+ Debug.Assert(m_converter != null, "[SerializationInfo.GetValue]m_converter!=null");
return m_converter.Convert(value, type);
}
diff --git a/src/mscorlib/src/System/Runtime/Serialization/SerializationInfoEnumerator.cs b/src/mscorlib/src/System/Runtime/Serialization/SerializationInfoEnumerator.cs
index 6b256a6e1f..32c65492e1 100644
--- a/src/mscorlib/src/System/Runtime/Serialization/SerializationInfoEnumerator.cs
+++ b/src/mscorlib/src/System/Runtime/Serialization/SerializationInfoEnumerator.cs
@@ -14,6 +14,7 @@
============================================================*/
namespace System.Runtime.Serialization {
using System;
+ using System.Diagnostics;
using System.Collections;
using System.Diagnostics.Contracts;
@@ -66,13 +67,13 @@ namespace System.Runtime.Serialization {
bool m_current;
internal SerializationInfoEnumerator(String[] members, Object[] info, Type[] types, int numItems) {
- Contract.Assert(members!=null, "[SerializationInfoEnumerator.ctor]members!=null");
- Contract.Assert(info!=null, "[SerializationInfoEnumerator.ctor]info!=null");
- Contract.Assert(types!=null, "[SerializationInfoEnumerator.ctor]types!=null");
- Contract.Assert(numItems>=0, "[SerializationInfoEnumerator.ctor]numItems>=0");
- Contract.Assert(members.Length>=numItems, "[SerializationInfoEnumerator.ctor]members.Length>=numItems");
- Contract.Assert(info.Length>=numItems, "[SerializationInfoEnumerator.ctor]info.Length>=numItems");
- Contract.Assert(types.Length>=numItems, "[SerializationInfoEnumerator.ctor]types.Length>=numItems");
+ Debug.Assert(members!=null, "[SerializationInfoEnumerator.ctor]members!=null");
+ Debug.Assert(info!=null, "[SerializationInfoEnumerator.ctor]info!=null");
+ Debug.Assert(types!=null, "[SerializationInfoEnumerator.ctor]types!=null");
+ Debug.Assert(numItems>=0, "[SerializationInfoEnumerator.ctor]numItems>=0");
+ Debug.Assert(members.Length>=numItems, "[SerializationInfoEnumerator.ctor]members.Length>=numItems");
+ Debug.Assert(info.Length>=numItems, "[SerializationInfoEnumerator.ctor]info.Length>=numItems");
+ Debug.Assert(types.Length>=numItems, "[SerializationInfoEnumerator.ctor]types.Length>=numItems");
m_members = members;
m_data = info;