1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
|
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.Runtime.Serialization
{
using System;
using System.Security;
using System.Security.Permissions;
using System.Runtime.CompilerServices;
#if USE_REFEMIT
public sealed class SurrogateDataContract : DataContract
#else
internal sealed class SurrogateDataContract : DataContract
#endif
{
[Fx.Tag.SecurityNote(Critical = "Holds instance of CriticalHelper which keeps state that is cached statically for serialization."
+ " Static fields are marked SecurityCritical or readonly to prevent data from being modified or leaked to other components in appdomain.")]
[SecurityCritical]
SurrogateDataContractCriticalHelper helper;
[Fx.Tag.SecurityNote(Critical = "Initializes SecurityCritical field 'helper'.",
Safe = "Doesn't leak anything.")]
[SecuritySafeCritical]
internal SurrogateDataContract(Type type, ISerializationSurrogate serializationSurrogate)
: base(new SurrogateDataContractCriticalHelper(type, serializationSurrogate))
{
helper = base.Helper as SurrogateDataContractCriticalHelper;
}
internal ISerializationSurrogate SerializationSurrogate
{
[Fx.Tag.SecurityNote(Critical = "Fetches the critical serializationSurrogate property.",
Safe = "serializationSurrogate only needs to be protected for write.")]
[SecuritySafeCritical]
get { return helper.SerializationSurrogate; }
}
public override void WriteXmlValue(XmlWriterDelegator xmlWriter, object obj, XmlObjectSerializerWriteContext context)
{
SerializationInfo serInfo = new SerializationInfo(UnderlyingType, XmlObjectSerializer.FormatterConverter, !context.UnsafeTypeForwardingEnabled);
SerializationSurrogateGetObjectData(obj, serInfo, context.GetStreamingContext());
context.WriteSerializationInfo(xmlWriter, UnderlyingType, serInfo);
}
[Fx.Tag.SecurityNote(Critical = "Calls the critical methods of ISurrogateSelector", Safe = "Demands for FullTrust")]
[SecuritySafeCritical]
[PermissionSet(SecurityAction.Demand, Unrestricted = true)]
[MethodImpl(MethodImplOptions.NoInlining)]
object SerializationSurrogateSetObjectData(object obj, SerializationInfo serInfo, StreamingContext context)
{
return SerializationSurrogate.SetObjectData(obj, serInfo, context, null);
}
[Fx.Tag.SecurityNote(Critical = "Calls the critical methods of IObjectReference", Safe = "Demands for FullTrust")]
[SecuritySafeCritical]
[PermissionSet(SecurityAction.Demand, Unrestricted = true)]
[MethodImpl(MethodImplOptions.NoInlining)]
internal static object GetRealObject(IObjectReference obj, StreamingContext context)
{
return obj.GetRealObject(context);
}
[Fx.Tag.SecurityNote(Critical = "Calls the critical methods of FormatterServices", Safe = "Demands for FullTrust")]
[SecuritySafeCritical]
[PermissionSet(SecurityAction.Demand, Unrestricted = true)]
[MethodImpl(MethodImplOptions.NoInlining)]
object GetUninitializedObject(Type objType)
{
return FormatterServices.GetUninitializedObject(objType);
}
[Fx.Tag.SecurityNote(Critical = "Calls the critical methods of ISerializationSurrogate", Safe = "Demands for FullTrust")]
[SecuritySafeCritical]
[PermissionSet(SecurityAction.Demand, Unrestricted = true)]
[MethodImpl(MethodImplOptions.NoInlining)]
void SerializationSurrogateGetObjectData(object obj, SerializationInfo serInfo, StreamingContext context)
{
SerializationSurrogate.GetObjectData(obj, serInfo, context);
}
public override object ReadXmlValue(XmlReaderDelegator xmlReader, XmlObjectSerializerReadContext context)
{
xmlReader.Read();
Type objType = UnderlyingType;
object obj = objType.IsArray ? Array.CreateInstance(objType.GetElementType(), 0) : GetUninitializedObject(objType);
context.AddNewObject(obj);
string objectId = context.GetObjectId();
SerializationInfo serInfo = context.ReadSerializationInfo(xmlReader, objType);
object newObj = SerializationSurrogateSetObjectData(obj, serInfo, context.GetStreamingContext());
if (newObj == null)
newObj = obj;
if (newObj is IDeserializationCallback)
((IDeserializationCallback)newObj).OnDeserialization(null);
if (newObj is IObjectReference)
newObj = GetRealObject((IObjectReference)newObj, context.GetStreamingContext());
context.ReplaceDeserializedObject(objectId, obj, newObj);
xmlReader.ReadEndElement();
return newObj;
}
[Fx.Tag.SecurityNote(Critical = "Holds all state used for for (de)serializing with ISerializationSurrogate."
+ " Since it accesses data on the base type that is cached statically, we lock down access to it.")]
#if !NO_SECURITY_ATTRIBUTES
[SecurityCritical(SecurityCriticalScope.Everything)]
#endif
class SurrogateDataContractCriticalHelper : DataContract.DataContractCriticalHelper
{
ISerializationSurrogate serializationSurrogate;
internal SurrogateDataContractCriticalHelper(Type type, ISerializationSurrogate serializationSurrogate)
: base(type)
{
this.serializationSurrogate = serializationSurrogate;
string name, ns;
DataContract.GetDefaultStableName(DataContract.GetClrTypeFullName(type), out name, out ns);
SetDataContractName(CreateQualifiedName(name, ns));
}
internal ISerializationSurrogate SerializationSurrogate
{
get { return serializationSurrogate; }
}
}
}
}
|