| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584 |
- //------------------------------------------------------------
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //------------------------------------------------------------
- namespace System.Runtime.Serialization
- {
- using System;
- using System.IO;
- using System.Xml;
- using System.Security;
- using System.Collections;
- using System.Security.Permissions;
- using System.Runtime.CompilerServices;
- using System.Runtime.Serialization.Formatters;
- using System.Collections.Generic;
- #if !NO_CONFIGURATION
- using System.Runtime.Serialization.Configuration;
- #endif
- using System.Reflection;
- public sealed class NetDataContractSerializer : XmlObjectSerializer, IFormatter
- {
- XmlDictionaryString rootName;
- XmlDictionaryString rootNamespace;
- StreamingContext context;
- SerializationBinder binder;
- ISurrogateSelector surrogateSelector;
- int maxItemsInObjectGraph;
- bool ignoreExtensionDataObject;
- FormatterAssemblyStyle assemblyFormat;
- DataContract cachedDataContract;
- static Hashtable typeNameCache = new Hashtable();
- public NetDataContractSerializer()
- : this(new StreamingContext(StreamingContextStates.All))
- {
- }
- public NetDataContractSerializer(StreamingContext context)
- : this(context, Int32.MaxValue, false, FormatterAssemblyStyle.Full, null)
- {
- }
- public NetDataContractSerializer(StreamingContext context,
- int maxItemsInObjectGraph,
- bool ignoreExtensionDataObject,
- FormatterAssemblyStyle assemblyFormat,
- ISurrogateSelector surrogateSelector)
- {
- Initialize(context, maxItemsInObjectGraph, ignoreExtensionDataObject, assemblyFormat, surrogateSelector);
- }
- public NetDataContractSerializer(string rootName, string rootNamespace)
- : this(rootName, rootNamespace, new StreamingContext(StreamingContextStates.All), Int32.MaxValue, false, FormatterAssemblyStyle.Full, null)
- {
- }
- public NetDataContractSerializer(string rootName, string rootNamespace,
- StreamingContext context,
- int maxItemsInObjectGraph,
- bool ignoreExtensionDataObject,
- FormatterAssemblyStyle assemblyFormat,
- ISurrogateSelector surrogateSelector)
- {
- XmlDictionary dictionary = new XmlDictionary(2);
- Initialize(dictionary.Add(rootName), dictionary.Add(DataContract.GetNamespace(rootNamespace)), context, maxItemsInObjectGraph, ignoreExtensionDataObject, assemblyFormat, surrogateSelector);
- }
- public NetDataContractSerializer(XmlDictionaryString rootName, XmlDictionaryString rootNamespace)
- : this(rootName, rootNamespace, new StreamingContext(StreamingContextStates.All), Int32.MaxValue, false, FormatterAssemblyStyle.Full, null)
- {
- }
- public NetDataContractSerializer(XmlDictionaryString rootName, XmlDictionaryString rootNamespace,
- StreamingContext context,
- int maxItemsInObjectGraph,
- bool ignoreExtensionDataObject,
- FormatterAssemblyStyle assemblyFormat,
- ISurrogateSelector surrogateSelector)
- {
- Initialize(rootName, rootNamespace, context, maxItemsInObjectGraph, ignoreExtensionDataObject, assemblyFormat, surrogateSelector);
- }
- void Initialize(StreamingContext context,
- int maxItemsInObjectGraph,
- bool ignoreExtensionDataObject,
- FormatterAssemblyStyle assemblyFormat,
- ISurrogateSelector surrogateSelector)
- {
- this.context = context;
- if (maxItemsInObjectGraph < 0)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("maxItemsInObjectGraph", SR.GetString(SR.ValueMustBeNonNegative)));
- this.maxItemsInObjectGraph = maxItemsInObjectGraph;
- this.ignoreExtensionDataObject = ignoreExtensionDataObject;
- this.surrogateSelector = surrogateSelector;
- this.AssemblyFormat = assemblyFormat;
- }
- void Initialize(XmlDictionaryString rootName, XmlDictionaryString rootNamespace,
- StreamingContext context,
- int maxItemsInObjectGraph,
- bool ignoreExtensionDataObject,
- FormatterAssemblyStyle assemblyFormat,
- ISurrogateSelector surrogateSelector)
- {
- Initialize(context, maxItemsInObjectGraph, ignoreExtensionDataObject, assemblyFormat, surrogateSelector);
- this.rootName = rootName;
- this.rootNamespace = rootNamespace;
- }
- static bool? unsafeTypeForwardingEnabled;
- internal static bool UnsafeTypeForwardingEnabled
- {
- [Fx.Tag.SecurityNote(Critical = "Calls Security Critical method NetDataContractSerializerSection.TryUnsafeGetSection.", Safe = "The ConfigSection instance is not leaked.")]
- [SecuritySafeCritical]
- get
- {
- if (unsafeTypeForwardingEnabled == null)
- {
- #if NO_CONFIGURATION
- unsafeTypeForwardingEnabled = false;
- #else
- NetDataContractSerializerSection section;
- if (NetDataContractSerializerSection.TryUnsafeGetSection(out section))
- {
- unsafeTypeForwardingEnabled = section.EnableUnsafeTypeForwarding;
- }
- else
- {
- unsafeTypeForwardingEnabled = false;
- }
- #endif
- }
- Fx.Assert(unsafeTypeForwardingEnabled != null, "unsafeTypeForwardingEnabled should not be null.");
- return unsafeTypeForwardingEnabled.Value;
- }
- }
- public StreamingContext Context
- {
- get { return context; }
- set { context = value; }
- }
- public SerializationBinder Binder
- {
- get { return binder; }
- set { binder = value; }
- }
- public ISurrogateSelector SurrogateSelector
- {
- get { return surrogateSelector; }
- set { surrogateSelector = value; }
- }
- public FormatterAssemblyStyle AssemblyFormat
- {
- get { return assemblyFormat; }
- set
- {
- if (value != FormatterAssemblyStyle.Full && value != FormatterAssemblyStyle.Simple)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.InvalidAssemblyFormat, value)));
- assemblyFormat = value;
- }
- }
- public int MaxItemsInObjectGraph
- {
- get { return maxItemsInObjectGraph; }
- }
- public bool IgnoreExtensionDataObject
- {
- get { return ignoreExtensionDataObject; }
- }
- public void Serialize(Stream stream, object graph)
- {
- base.WriteObject(stream, graph);
- }
- public object Deserialize(Stream stream)
- {
- return base.ReadObject(stream);
- }
- internal override void InternalWriteObject(XmlWriterDelegator writer, object graph)
- {
- Hashtable surrogateDataContracts = null;
- DataContract contract = GetDataContract(graph, ref surrogateDataContracts);
- InternalWriteStartObject(writer, graph, contract);
- InternalWriteObjectContent(writer, graph, contract, surrogateDataContracts);
- InternalWriteEndObject(writer);
- }
- public override void WriteObject(XmlWriter writer, object graph)
- {
- WriteObjectHandleExceptions(new XmlWriterDelegator(writer), graph);
- }
- public override void WriteStartObject(XmlWriter writer, object graph)
- {
- WriteStartObjectHandleExceptions(new XmlWriterDelegator(writer), graph);
- }
- public override void WriteObjectContent(XmlWriter writer, object graph)
- {
- WriteObjectContentHandleExceptions(new XmlWriterDelegator(writer), graph);
- }
- public override void WriteEndObject(XmlWriter writer)
- {
- WriteEndObjectHandleExceptions(new XmlWriterDelegator(writer));
- }
- public override void WriteStartObject(XmlDictionaryWriter writer, object graph)
- {
- WriteStartObjectHandleExceptions(new XmlWriterDelegator(writer), graph);
- }
- internal override void InternalWriteStartObject(XmlWriterDelegator writer, object graph)
- {
- Hashtable surrogateDataContracts = null;
- DataContract contract = GetDataContract(graph, ref surrogateDataContracts);
- InternalWriteStartObject(writer, graph, contract);
- }
- void InternalWriteStartObject(XmlWriterDelegator writer, object graph, DataContract contract)
- {
- WriteRootElement(writer, contract, rootName, rootNamespace, CheckIfNeedsContractNsAtRoot(rootName, rootNamespace, contract));
- }
- public override void WriteObjectContent(XmlDictionaryWriter writer, object graph)
- {
- WriteObjectContentHandleExceptions(new XmlWriterDelegator(writer), graph);
- }
- internal override void InternalWriteObjectContent(XmlWriterDelegator writer, object graph)
- {
- Hashtable surrogateDataContracts = null;
- DataContract contract = GetDataContract(graph, ref surrogateDataContracts);
- InternalWriteObjectContent(writer, graph, contract, surrogateDataContracts);
- }
- void InternalWriteObjectContent(XmlWriterDelegator writer, object graph, DataContract contract, Hashtable surrogateDataContracts)
- {
- if (MaxItemsInObjectGraph == 0)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.ExceededMaxItemsQuota, MaxItemsInObjectGraph)));
- if (IsRootXmlAny(rootName, contract))
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.IsAnyNotSupportedByNetDataContractSerializer, contract.UnderlyingType)));
- }
- else if (graph == null)
- {
- WriteNull(writer);
- }
- else
- {
- Type graphType = graph.GetType();
- if (contract.UnderlyingType != graphType)
- contract = GetDataContract(graph, ref surrogateDataContracts);
- XmlObjectSerializerWriteContext context = null;
- if (contract.CanContainReferences)
- {
- context = XmlObjectSerializerWriteContext.CreateContext(this, surrogateDataContracts);
- context.HandleGraphAtTopLevel(writer, graph, contract);
- }
- WriteClrTypeInfo(writer, contract, binder);
- contract.WriteXmlValue(writer, graph, context);
- }
- }
- // Update the overloads whenever you are changing this method
- internal static void WriteClrTypeInfo(XmlWriterDelegator writer, DataContract dataContract, SerializationBinder binder)
- {
- if (!dataContract.IsISerializable && !(dataContract is SurrogateDataContract))
- {
- TypeInformation typeInformation = null;
- Type clrType = dataContract.OriginalUnderlyingType;
- string clrTypeName = null;
- string clrAssemblyName = null;
- if (binder != null)
- {
- binder.BindToName(clrType, out clrAssemblyName, out clrTypeName);
- }
- if (clrTypeName == null)
- {
- typeInformation = NetDataContractSerializer.GetTypeInformation(clrType);
- clrTypeName = typeInformation.FullTypeName;
- }
- if (clrAssemblyName == null)
- {
- clrAssemblyName = (typeInformation == null) ?
- NetDataContractSerializer.GetTypeInformation(clrType).AssemblyString :
- typeInformation.AssemblyString;
- // Throw in the [TypeForwardedFrom] case to prevent a partially trusted assembly from forwarding itself to an assembly with higher privileges
- if (!UnsafeTypeForwardingEnabled && !clrType.Assembly.IsFullyTrusted && !IsAssemblyNameForwardingSafe(clrType.Assembly.FullName, clrAssemblyName))
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.TypeCannotBeForwardedFrom, DataContract.GetClrTypeFullName(clrType), clrType.Assembly.FullName, clrAssemblyName)));
- }
- }
- WriteClrTypeInfo(writer, clrTypeName, clrAssemblyName);
- }
- }
- // Update the overloads whenever you are changing this method
- internal static void WriteClrTypeInfo(XmlWriterDelegator writer, Type dataContractType, SerializationBinder binder, string defaultClrTypeName, string defaultClrAssemblyName)
- {
- string clrTypeName = null;
- string clrAssemblyName = null;
- if (binder != null)
- {
- binder.BindToName(dataContractType, out clrAssemblyName, out clrTypeName);
- }
- if (clrTypeName == null)
- {
- clrTypeName = defaultClrTypeName;
- }
- if (clrAssemblyName == null)
- {
- clrAssemblyName = defaultClrAssemblyName;
- }
- WriteClrTypeInfo(writer, clrTypeName, clrAssemblyName);
- }
- // Update the overloads whenever you are changing this method
- internal static void WriteClrTypeInfo(XmlWriterDelegator writer, Type dataContractType, SerializationBinder binder, SerializationInfo serInfo)
- {
- TypeInformation typeInformation = null;
- string clrTypeName = null;
- string clrAssemblyName = null;
- if (binder != null)
- {
- binder.BindToName(dataContractType, out clrAssemblyName, out clrTypeName);
- }
- if (clrTypeName == null)
- {
- if (serInfo.IsFullTypeNameSetExplicit)
- {
- clrTypeName = serInfo.FullTypeName;
- }
- else
- {
- typeInformation = NetDataContractSerializer.GetTypeInformation(serInfo.ObjectType);
- clrTypeName = typeInformation.FullTypeName;
- }
- }
- if (clrAssemblyName == null)
- {
- if (serInfo.IsAssemblyNameSetExplicit)
- {
- clrAssemblyName = serInfo.AssemblyName;
- }
- else
- {
- clrAssemblyName = (typeInformation == null) ?
- NetDataContractSerializer.GetTypeInformation(serInfo.ObjectType).AssemblyString :
- typeInformation.AssemblyString;
- }
- }
- WriteClrTypeInfo(writer, clrTypeName, clrAssemblyName);
- }
- static void WriteClrTypeInfo(XmlWriterDelegator writer, string clrTypeName, string clrAssemblyName)
- {
- if (clrTypeName != null)
- writer.WriteAttributeString(Globals.SerPrefix, DictionaryGlobals.ClrTypeLocalName, DictionaryGlobals.SerializationNamespace, DataContract.GetClrTypeString(clrTypeName));
- if (clrAssemblyName != null)
- writer.WriteAttributeString(Globals.SerPrefix, DictionaryGlobals.ClrAssemblyLocalName, DictionaryGlobals.SerializationNamespace, DataContract.GetClrTypeString(clrAssemblyName));
- }
- public override void WriteEndObject(XmlDictionaryWriter writer)
- {
- WriteEndObjectHandleExceptions(new XmlWriterDelegator(writer));
- }
- internal override void InternalWriteEndObject(XmlWriterDelegator writer)
- {
- writer.WriteEndElement();
- }
- public override object ReadObject(XmlReader reader)
- {
- return ReadObjectHandleExceptions(new XmlReaderDelegator(reader), true /*verifyObjectName*/);
- }
- public override object ReadObject(XmlReader reader, bool verifyObjectName)
- {
- return ReadObjectHandleExceptions(new XmlReaderDelegator(reader), verifyObjectName);
- }
- public override bool IsStartObject(XmlReader reader)
- {
- return IsStartObjectHandleExceptions(new XmlReaderDelegator(reader));
- }
- public override object ReadObject(XmlDictionaryReader reader, bool verifyObjectName)
- {
- return ReadObjectHandleExceptions(new XmlReaderDelegator(reader), verifyObjectName);
- }
- public override bool IsStartObject(XmlDictionaryReader reader)
- {
- return IsStartObjectHandleExceptions(new XmlReaderDelegator(reader));
- }
- internal override object InternalReadObject(XmlReaderDelegator xmlReader, bool verifyObjectName)
- {
- if (MaxItemsInObjectGraph == 0)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.ExceededMaxItemsQuota, MaxItemsInObjectGraph)));
- // verifyObjectName has no effect in SharedType mode
- if (!IsStartElement(xmlReader))
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationExceptionWithReaderDetails(SR.GetString(SR.ExpectingElementAtDeserialize, XmlNodeType.Element), xmlReader));
- }
- XmlObjectSerializerReadContext context = XmlObjectSerializerReadContext.CreateContext(this);
- return context.InternalDeserialize(xmlReader, null, null, null);
- }
- internal override bool InternalIsStartObject(XmlReaderDelegator reader)
- {
- return IsStartElement(reader);
- }
- internal DataContract GetDataContract(object obj, ref Hashtable surrogateDataContracts)
- {
- return GetDataContract(((obj == null) ? Globals.TypeOfObject : obj.GetType()), ref surrogateDataContracts);
- }
- internal DataContract GetDataContract(Type type, ref Hashtable surrogateDataContracts)
- {
- return GetDataContract(type.TypeHandle, type, ref surrogateDataContracts);
- }
- internal DataContract GetDataContract(RuntimeTypeHandle typeHandle, Type type, ref Hashtable surrogateDataContracts)
- {
- DataContract dataContract = GetDataContractFromSurrogateSelector(surrogateSelector, Context, typeHandle, type, ref surrogateDataContracts);
- if (dataContract != null)
- return dataContract;
- if (cachedDataContract == null)
- {
- dataContract = DataContract.GetDataContract(typeHandle, type, SerializationMode.SharedType);
- cachedDataContract = dataContract;
- return dataContract;
- }
- DataContract currentCachedDataContract = cachedDataContract;
- if (currentCachedDataContract.UnderlyingType.TypeHandle.Equals(typeHandle))
- return currentCachedDataContract;
- return DataContract.GetDataContract(typeHandle, type, SerializationMode.SharedType);
- }
- [Fx.Tag.SecurityNote(Critical = "Calls the critical methods of ISurrogateSelector", Safe = "Demands for FullTrust")]
- [SecuritySafeCritical]
- [PermissionSet(SecurityAction.Demand, Unrestricted = true)]
- [MethodImpl(MethodImplOptions.NoInlining)]
- static ISerializationSurrogate GetSurrogate(Type type, ISurrogateSelector surrogateSelector, StreamingContext context)
- {
- ISurrogateSelector surrogateSelectorNotUsed;
- return surrogateSelector.GetSurrogate(type, context, out surrogateSelectorNotUsed);
- }
- internal static DataContract GetDataContractFromSurrogateSelector(ISurrogateSelector surrogateSelector, StreamingContext context, RuntimeTypeHandle typeHandle, Type type, ref Hashtable surrogateDataContracts)
- {
- if (surrogateSelector == null)
- return null;
- if (type == null)
- type = Type.GetTypeFromHandle(typeHandle);
- DataContract builtInDataContract = DataContract.GetBuiltInDataContract(type);
- if (builtInDataContract != null)
- return builtInDataContract;
- if (surrogateDataContracts != null)
- {
- DataContract cachedSurrogateContract = (DataContract)surrogateDataContracts[type];
- if (cachedSurrogateContract != null)
- return cachedSurrogateContract;
- }
- DataContract surrogateContract = null;
- ISerializationSurrogate surrogate = GetSurrogate(type, surrogateSelector, context);
- if (surrogate != null)
- surrogateContract = new SurrogateDataContract(type, surrogate);
- else if (type.IsArray)
- {
- Type elementType = type.GetElementType();
- DataContract itemContract = GetDataContractFromSurrogateSelector(surrogateSelector, context, elementType.TypeHandle, elementType, ref surrogateDataContracts);
- if (itemContract == null)
- itemContract = DataContract.GetDataContract(elementType.TypeHandle, elementType, SerializationMode.SharedType);
- surrogateContract = new CollectionDataContract(type, itemContract);
- }
- if (surrogateContract != null)
- {
- if (surrogateDataContracts == null)
- surrogateDataContracts = new Hashtable();
- surrogateDataContracts.Add(type, surrogateContract);
- return surrogateContract;
- }
- return null;
- }
- internal static TypeInformation GetTypeInformation(Type type)
- {
- TypeInformation typeInformation = null;
- object typeInformationObject = typeNameCache[type];
- if (typeInformationObject == null)
- {
- bool hasTypeForwardedFrom;
- string assemblyName = DataContract.GetClrAssemblyName(type, out hasTypeForwardedFrom);
- typeInformation = new TypeInformation(DataContract.GetClrTypeFullNameUsingTypeForwardedFromAttribute(type), assemblyName, hasTypeForwardedFrom);
- lock (typeNameCache)
- {
- typeNameCache[type] = typeInformation;
- }
- }
- else
- {
- typeInformation = (TypeInformation)typeInformationObject;
- }
- return typeInformation;
- }
- static bool IsAssemblyNameForwardingSafe(string originalAssemblyName, string newAssemblyName)
- {
- if (originalAssemblyName == newAssemblyName)
- {
- return true;
- }
- AssemblyName originalAssembly = new AssemblyName(originalAssemblyName);
- AssemblyName newAssembly = new AssemblyName(newAssemblyName);
- // mscorlib will get loaded by the runtime regardless of its string casing or its public key token,
- // so setting the assembly name to mscorlib is always unsafe
- if (string.Equals(newAssembly.Name, Globals.MscorlibAssemblySimpleName, StringComparison.OrdinalIgnoreCase) ||
- string.Equals(newAssembly.Name, Globals.MscorlibFileName, StringComparison.OrdinalIgnoreCase))
- {
- return false;
- }
- return IsPublicKeyTokenForwardingSafe(originalAssembly.GetPublicKeyToken(), newAssembly.GetPublicKeyToken());
- }
- static bool IsPublicKeyTokenForwardingSafe(byte[] sourceToken, byte[] destinationToken)
- {
- if (sourceToken == null || destinationToken == null || sourceToken.Length == 0 || destinationToken.Length == 0 || sourceToken.Length != destinationToken.Length)
- {
- return false;
- }
-
- for (int i = 0; i < sourceToken.Length; i++)
- {
- if (sourceToken[i] != destinationToken[i])
- {
- return false;
- }
- }
- return true;
- }
- }
- }
|