| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531 |
- //------------------------------------------------------------
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //------------------------------------------------------------
- namespace System.Runtime.Serialization
- {
- using System;
- using System.Collections;
- using System.Diagnostics;
- using System.Globalization;
- using System.IO;
- using System.Reflection;
- using System.Text;
- using System.Xml;
- using DataContractDictionary = System.Collections.Generic.Dictionary<System.Xml.XmlQualifiedName, DataContract>;
- using System.Collections.Generic;
- using System.Runtime.Serialization.Diagnostics.Application;
- using System.Runtime.Serialization.Formatters;
- using System.Security;
- using System.Security.Permissions;
- using System.Runtime.CompilerServices;
- #if USE_REFEMIT
- public class XmlObjectSerializerReadContextComplex : XmlObjectSerializerReadContext
- #else
- internal class XmlObjectSerializerReadContextComplex : XmlObjectSerializerReadContext
- #endif
- {
- static Hashtable dataContractTypeCache = new Hashtable();
- bool preserveObjectReferences;
- protected IDataContractSurrogate dataContractSurrogate;
- SerializationMode mode;
- SerializationBinder binder;
- ISurrogateSelector surrogateSelector;
- FormatterAssemblyStyle assemblyFormat;
- Hashtable surrogateDataContracts;
- internal XmlObjectSerializerReadContextComplex(DataContractSerializer serializer, DataContract rootTypeDataContract, DataContractResolver dataContractResolver)
- : base(serializer, rootTypeDataContract, dataContractResolver)
- {
- this.mode = SerializationMode.SharedContract;
- this.preserveObjectReferences = serializer.PreserveObjectReferences;
- this.dataContractSurrogate = serializer.DataContractSurrogate;
- }
- internal XmlObjectSerializerReadContextComplex(NetDataContractSerializer serializer)
- : base(serializer)
- {
- this.mode = SerializationMode.SharedType;
- this.preserveObjectReferences = true;
- this.binder = serializer.Binder;
- this.surrogateSelector = serializer.SurrogateSelector;
- this.assemblyFormat = serializer.AssemblyFormat;
- }
- internal XmlObjectSerializerReadContextComplex(XmlObjectSerializer serializer, int maxItemsInObjectGraph, StreamingContext streamingContext, bool ignoreExtensionDataObject)
- : base(serializer, maxItemsInObjectGraph, streamingContext, ignoreExtensionDataObject)
- {
- }
- internal override SerializationMode Mode
- {
- get { return mode; }
- }
- internal override DataContract GetDataContract(int id, RuntimeTypeHandle typeHandle)
- {
- DataContract dataContract = null;
- if (mode == SerializationMode.SharedType && surrogateSelector != null)
- {
- dataContract = NetDataContractSerializer.GetDataContractFromSurrogateSelector(surrogateSelector, GetStreamingContext(), typeHandle, null /*type*/, ref surrogateDataContracts);
- }
- if (dataContract != null)
- {
- if (this.IsGetOnlyCollection && dataContract is SurrogateDataContract)
- {
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.SurrogatesWithGetOnlyCollectionsNotSupportedSerDeser,
- DataContract.GetClrTypeFullName(dataContract.UnderlyingType))));
- }
- return dataContract;
- }
- return base.GetDataContract(id, typeHandle);
- }
- internal override DataContract GetDataContract(RuntimeTypeHandle typeHandle, Type type)
- {
- DataContract dataContract = null;
- if (mode == SerializationMode.SharedType && surrogateSelector != null)
- {
- dataContract = NetDataContractSerializer.GetDataContractFromSurrogateSelector(surrogateSelector, GetStreamingContext(), typeHandle, type, ref surrogateDataContracts);
- }
- if (dataContract != null)
- {
- if (this.IsGetOnlyCollection && dataContract is SurrogateDataContract)
- {
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.SurrogatesWithGetOnlyCollectionsNotSupportedSerDeser,
- DataContract.GetClrTypeFullName(dataContract.UnderlyingType))));
- }
- return dataContract;
- }
- return base.GetDataContract(typeHandle, type);
- }
- public override object InternalDeserialize(XmlReaderDelegator xmlReader, int declaredTypeID, RuntimeTypeHandle declaredTypeHandle, string name, string ns)
- {
- if (mode == SerializationMode.SharedContract)
- {
- if (dataContractSurrogate == null)
- return base.InternalDeserialize(xmlReader, declaredTypeID, declaredTypeHandle, name, ns);
- else
- return InternalDeserializeWithSurrogate(xmlReader, Type.GetTypeFromHandle(declaredTypeHandle), null /*surrogateDataContract*/, name, ns);
- }
- else
- {
- return InternalDeserializeInSharedTypeMode(xmlReader, declaredTypeID, Type.GetTypeFromHandle(declaredTypeHandle), name, ns);
- }
- }
- internal override object InternalDeserialize(XmlReaderDelegator xmlReader, Type declaredType, string name, string ns)
- {
- if (mode == SerializationMode.SharedContract)
- {
- if (dataContractSurrogate == null)
- return base.InternalDeserialize(xmlReader, declaredType, name, ns);
- else
- return InternalDeserializeWithSurrogate(xmlReader, declaredType, null /*surrogateDataContract*/, name, ns);
- }
- else
- {
- return InternalDeserializeInSharedTypeMode(xmlReader, -1, declaredType, name, ns);
- }
- }
- internal override object InternalDeserialize(XmlReaderDelegator xmlReader, Type declaredType, DataContract dataContract, string name, string ns)
- {
- if (mode == SerializationMode.SharedContract)
- {
- if (dataContractSurrogate == null)
- return base.InternalDeserialize(xmlReader, declaredType, dataContract, name, ns);
- else
- return InternalDeserializeWithSurrogate(xmlReader, declaredType, dataContract, name, ns);
- }
- else
- {
- return InternalDeserializeInSharedTypeMode(xmlReader, -1, declaredType, name, ns);
- }
- }
- object InternalDeserializeInSharedTypeMode(XmlReaderDelegator xmlReader, int declaredTypeID, Type declaredType, string name, string ns)
- {
- object retObj = null;
- if (TryHandleNullOrRef(xmlReader, declaredType, name, ns, ref retObj))
- return retObj;
- DataContract dataContract;
- string assemblyName = attributes.ClrAssembly;
- string typeName = attributes.ClrType;
- if (assemblyName != null && typeName != null)
- {
- Assembly assembly;
- Type type;
- dataContract = ResolveDataContractInSharedTypeMode(assemblyName, typeName, out assembly, out type);
- if (dataContract == null)
- {
- if (assembly == null)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.AssemblyNotFound, assemblyName)));
- if (type == null)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.ClrTypeNotFound, assembly.FullName, typeName)));
- }
- //Array covariance is not supported in XSD. If declared type is array, data is sent in format of base array
- if (declaredType != null && declaredType.IsArray)
- dataContract = (declaredTypeID < 0) ? GetDataContract(declaredType) : GetDataContract(declaredTypeID, declaredType.TypeHandle);
- }
- else
- {
- if (assemblyName != null)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(XmlObjectSerializer.TryAddLineInfo(xmlReader, SR.GetString(SR.AttributeNotFound, Globals.SerializationNamespace, Globals.ClrTypeLocalName, xmlReader.NodeType, xmlReader.NamespaceURI, xmlReader.LocalName))));
- else if (typeName != null)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(XmlObjectSerializer.TryAddLineInfo(xmlReader, SR.GetString(SR.AttributeNotFound, Globals.SerializationNamespace, Globals.ClrAssemblyLocalName, xmlReader.NodeType, xmlReader.NamespaceURI, xmlReader.LocalName))));
- else if (declaredType == null)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(XmlObjectSerializer.TryAddLineInfo(xmlReader, SR.GetString(SR.AttributeNotFound, Globals.SerializationNamespace, Globals.ClrTypeLocalName, xmlReader.NodeType, xmlReader.NamespaceURI, xmlReader.LocalName))));
- dataContract = (declaredTypeID < 0) ? GetDataContract(declaredType) : GetDataContract(declaredTypeID, declaredType.TypeHandle);
- }
- return ReadDataContractValue(dataContract, xmlReader);
- }
- object InternalDeserializeWithSurrogate(XmlReaderDelegator xmlReader, Type declaredType, DataContract surrogateDataContract, string name, string ns)
- {
- if (TD.DCDeserializeWithSurrogateStartIsEnabled())
- {
- TD.DCDeserializeWithSurrogateStart(declaredType.FullName);
- }
- DataContract dataContract = surrogateDataContract ??
- GetDataContract(DataContractSurrogateCaller.GetDataContractType(dataContractSurrogate, declaredType));
- if (this.IsGetOnlyCollection && dataContract.UnderlyingType != declaredType)
- {
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.SurrogatesWithGetOnlyCollectionsNotSupportedSerDeser,
- DataContract.GetClrTypeFullName(declaredType))));
- }
- ReadAttributes(xmlReader);
- string objectId = GetObjectId();
- object oldObj = InternalDeserialize(xmlReader, name, ns, declaredType, ref dataContract);
- object obj = DataContractSurrogateCaller.GetDeserializedObject(dataContractSurrogate, oldObj, dataContract.UnderlyingType, declaredType);
- ReplaceDeserializedObject(objectId, oldObj, obj);
- if (TD.DCDeserializeWithSurrogateStopIsEnabled())
- {
- TD.DCDeserializeWithSurrogateStop();
- }
- return obj;
- }
- Type ResolveDataContractTypeInSharedTypeMode(string assemblyName, string typeName, out Assembly assembly)
- {
- assembly = null;
- Type type = null;
- if (binder != null)
- type = binder.BindToType(assemblyName, typeName);
- if (type == null)
- {
- XmlObjectDataContractTypeKey key = new XmlObjectDataContractTypeKey(assemblyName, typeName);
- XmlObjectDataContractTypeInfo dataContractTypeInfo = (XmlObjectDataContractTypeInfo)dataContractTypeCache[key];
- if (dataContractTypeInfo == null)
- {
- if (assemblyFormat == FormatterAssemblyStyle.Full)
- {
- if (assemblyName == Globals.MscorlibAssemblyName)
- {
- assembly = Globals.TypeOfInt.Assembly;
- }
- else
- {
- assembly = Assembly.Load(assemblyName);
- }
- if (assembly != null)
- type = assembly.GetType(typeName);
- }
- else
- {
- assembly = XmlObjectSerializerReadContextComplex.ResolveSimpleAssemblyName(assemblyName);
- if (assembly != null)
- {
- // Catching any exceptions that could be thrown from a failure on assembly load
- // This is necessary, for example, if there are generic parameters that are qualified with a version of the assembly that predates the one available
- try
- {
- type = assembly.GetType(typeName);
- }
- catch (TypeLoadException) { }
- catch (FileNotFoundException) { }
- catch (FileLoadException) { }
- catch (BadImageFormatException) { }
- if (type == null)
- {
- type = Type.GetType(typeName, XmlObjectSerializerReadContextComplex.ResolveSimpleAssemblyName, new TopLevelAssemblyTypeResolver(assembly).ResolveType, false /* throwOnError */);
- }
- }
- }
- if (type != null)
- {
- CheckTypeForwardedTo(assembly, type.Assembly, type);
- dataContractTypeInfo = new XmlObjectDataContractTypeInfo(assembly, type);
- lock (dataContractTypeCache)
- {
- if (!dataContractTypeCache.ContainsKey(key))
- {
- dataContractTypeCache[key] = dataContractTypeInfo;
- }
- }
- }
- }
- else
- {
- assembly = dataContractTypeInfo.Assembly;
- type = dataContractTypeInfo.Type;
- }
- }
- return type;
- }
- DataContract ResolveDataContractInSharedTypeMode(string assemblyName, string typeName, out Assembly assembly, out Type type)
- {
- type = ResolveDataContractTypeInSharedTypeMode(assemblyName, typeName, out assembly);
- if (type != null)
- {
- return GetDataContract(type);
- }
- return null;
- }
- protected override DataContract ResolveDataContractFromTypeName()
- {
- if (mode == SerializationMode.SharedContract)
- {
- return base.ResolveDataContractFromTypeName();
- }
- else
- {
- if (attributes.ClrAssembly != null && attributes.ClrType != null)
- {
- Assembly assembly;
- Type type;
- return ResolveDataContractInSharedTypeMode(attributes.ClrAssembly, attributes.ClrType, out assembly, out type);
- }
- }
- return null;
- }
- [Fx.Tag.SecurityNote(Critical = "Calls the critical methods of ISurrogateSelector", Safe = "Demands for FullTrust")]
- [SecuritySafeCritical]
- [PermissionSet(SecurityAction.Demand, Unrestricted = true)]
- [MethodImpl(MethodImplOptions.NoInlining)]
- bool CheckIfTypeSerializableForSharedTypeMode(Type memberType)
- {
- Fx.Assert(surrogateSelector != null, "Method should not be called when surrogateSelector is null.");
- ISurrogateSelector surrogateSelectorNotUsed;
- return (surrogateSelector.GetSurrogate(memberType, GetStreamingContext(), out surrogateSelectorNotUsed) != null);
- }
- internal override void CheckIfTypeSerializable(Type memberType, bool isMemberTypeSerializable)
- {
- if (mode == SerializationMode.SharedType && surrogateSelector != null &&
- CheckIfTypeSerializableForSharedTypeMode(memberType))
- {
- return;
- }
- else
- {
- if (dataContractSurrogate != null)
- {
- while (memberType.IsArray)
- memberType = memberType.GetElementType();
- memberType = DataContractSurrogateCaller.GetDataContractType(dataContractSurrogate, memberType);
- if (!DataContract.IsTypeSerializable(memberType))
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.TypeNotSerializable, memberType)));
- return;
- }
- }
- base.CheckIfTypeSerializable(memberType, isMemberTypeSerializable);
- }
- internal override Type GetSurrogatedType(Type type)
- {
- if (dataContractSurrogate == null)
- {
- return base.GetSurrogatedType(type);
- }
- else
- {
- type = DataContract.UnwrapNullableType(type);
- Type surrogateType = DataContractSerializer.GetSurrogatedType(dataContractSurrogate, type);
- if (this.IsGetOnlyCollection && surrogateType != type)
- {
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.SurrogatesWithGetOnlyCollectionsNotSupportedSerDeser,
- DataContract.GetClrTypeFullName(type))));
- }
- else
- {
- return surrogateType;
- }
- }
- }
- #if USE_REFEMIT
- public override int GetArraySize()
- #else
- internal override int GetArraySize()
- #endif
- {
- return preserveObjectReferences ? attributes.ArraySZSize : -1;
- }
- static Assembly ResolveSimpleAssemblyName(AssemblyName assemblyName)
- {
- return ResolveSimpleAssemblyName(assemblyName.FullName);
- }
- static Assembly ResolveSimpleAssemblyName(string assemblyName)
- {
- Assembly assembly;
- if (assemblyName == Globals.MscorlibAssemblyName)
- {
- assembly = Globals.TypeOfInt.Assembly;
- }
- else
- {
- assembly = Assembly.LoadWithPartialName(assemblyName);
- if (assembly == null)
- {
- AssemblyName an = new AssemblyName(assemblyName);
- an.Version = null;
- assembly = Assembly.LoadWithPartialName(an.FullName);
- }
- }
- return assembly;
- }
- [Fx.Tag.SecurityNote(Critical = "Gets the SecurityCritical PermissionSet for sourceAssembly and destinationAssembly.",
- Safe = "Doesn't leak anything.")]
- [SecuritySafeCritical]
- static void CheckTypeForwardedTo(Assembly sourceAssembly, Assembly destinationAssembly, Type resolvedType)
- {
- if (sourceAssembly != destinationAssembly && !NetDataContractSerializer.UnsafeTypeForwardingEnabled && !sourceAssembly.IsFullyTrusted)
- {
- #if !NO_DESKTOP_SECURITY
- // We have a TypeForwardedTo attribute
- if (!destinationAssembly.PermissionSet.IsSubsetOf(sourceAssembly.PermissionSet))
- {
- // We look for a matching TypeForwardedFrom attribute
- TypeInformation typeInfo = NetDataContractSerializer.GetTypeInformation(resolvedType);
- if (typeInfo.HasTypeForwardedFrom)
- {
- Assembly typeForwardedFromAssembly = null;
- try
- {
- // if this Assembly.Load fails, we still want to throw security exception
- typeForwardedFromAssembly = Assembly.Load(typeInfo.AssemblyString);
- }
- catch { }
- if (typeForwardedFromAssembly == sourceAssembly)
- {
- return;
- }
- }
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.CannotDeserializeForwardedType, DataContract.GetClrTypeFullName(resolvedType))));
- }
- #endif
- }
- }
- sealed class TopLevelAssemblyTypeResolver
- {
- Assembly topLevelAssembly;
- public TopLevelAssemblyTypeResolver(Assembly topLevelAssembly)
- {
- this.topLevelAssembly = topLevelAssembly;
- }
- public Type ResolveType(Assembly assembly, string simpleTypeName, bool ignoreCase)
- {
- if (assembly == null)
- assembly = topLevelAssembly;
- return assembly.GetType(simpleTypeName, false, ignoreCase);
- }
- }
- class XmlObjectDataContractTypeInfo
- {
- Assembly assembly;
- Type type;
- public XmlObjectDataContractTypeInfo(Assembly assembly, Type type)
- {
- this.assembly = assembly;
- this.type = type;
- }
- public Assembly Assembly
- {
- get
- {
- return this.assembly;
- }
- }
- public Type Type
- {
- get
- {
- return this.type;
- }
- }
- }
- class XmlObjectDataContractTypeKey
- {
- string assemblyName;
- string typeName;
- public XmlObjectDataContractTypeKey(string assemblyName, string typeName)
- {
- this.assemblyName = assemblyName;
- this.typeName = typeName;
- }
- public override bool Equals(object obj)
- {
- if (object.ReferenceEquals(this, obj))
- return true;
- XmlObjectDataContractTypeKey other = obj as XmlObjectDataContractTypeKey;
- if (other == null)
- return false;
- if (this.assemblyName != other.assemblyName)
- return false;
- if (this.typeName != other.typeName)
- return false;
- return true;
- }
- public override int GetHashCode()
- {
- int hashCode = 0;
- if (this.assemblyName != null)
- hashCode = this.assemblyName.GetHashCode();
- if (this.typeName != null)
- hashCode ^= this.typeName.GetHashCode();
- return hashCode;
- }
- }
- }
- }
|