| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464 |
- //-----------------------------------------------------------------------------
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //-----------------------------------------------------------------------------
- namespace System.Runtime.Serialization
- {
- using System;
- using System.Collections.Generic;
- using System.Reflection;
- using System.Security;
- using System.Security.Permissions;
- using System.Threading;
- using System.Xml;
- using System.Xml.Schema;
- using System.Xml.Serialization;
- using DataContractDictionary = System.Collections.Generic.Dictionary<System.Xml.XmlQualifiedName, DataContract>;
- internal delegate IXmlSerializable CreateXmlSerializableDelegate();
- #if USE_REFEMIT
- public sealed class XmlDataContract : DataContract
- #else
- internal sealed partial class XmlDataContract : 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]
- XmlDataContractCriticalHelper helper;
- [Fx.Tag.SecurityNote(Critical = "Initializes SecurityCritical field 'helper'.",
- Safe = "Doesn't leak anything.")]
- [SecuritySafeCritical]
- internal XmlDataContract()
- : base(new XmlDataContractCriticalHelper())
- {
- helper = base.Helper as XmlDataContractCriticalHelper;
- }
- [Fx.Tag.SecurityNote(Critical = "Initializes SecurityCritical field 'helper'.",
- Safe = "Doesn't leak anything.")]
- [SecuritySafeCritical]
- internal XmlDataContract(Type type)
- : base(new XmlDataContractCriticalHelper(type))
- {
- helper = base.Helper as XmlDataContractCriticalHelper;
- }
- internal override DataContractDictionary KnownDataContracts
- {
- [Fx.Tag.SecurityNote(Critical = "Fetches the critical KnownDataContracts property.",
- Safe = "KnownDataContracts only needs to be protected for write.")]
- [SecuritySafeCritical]
- get { return helper.KnownDataContracts; }
- [Fx.Tag.SecurityNote(Critical = "Sets the critical KnownDataContracts property.")]
- [SecurityCritical]
- set { helper.KnownDataContracts = value; }
- }
- internal XmlSchemaType XsdType
- {
- [Fx.Tag.SecurityNote(Critical = "Fetches the critical XsdType property.",
- Safe = "XsdType only needs to be protected for write.")]
- [SecuritySafeCritical]
- get { return helper.XsdType; }
- [Fx.Tag.SecurityNote(Critical = "Sets the critical XsdType property.")]
- [SecurityCritical]
- set { helper.XsdType = value; }
- }
- internal bool IsAnonymous
- {
- [Fx.Tag.SecurityNote(Critical = "Fetches the critical IsAnonymous property.",
- Safe = "IsAnonymous only needs to be protected for write.")]
- [SecuritySafeCritical]
- get { return helper.IsAnonymous; }
- }
- internal override bool HasRoot
- {
- [Fx.Tag.SecurityNote(Critical = "Fetches the critical HasRoot property.",
- Safe = "HasRoot only needs to be protected for write.")]
- [SecuritySafeCritical]
- get { return helper.HasRoot; }
- [Fx.Tag.SecurityNote(Critical = "Sets the critical HasRoot property.")]
- [SecurityCritical]
- set { helper.HasRoot = value; }
- }
- internal override XmlDictionaryString TopLevelElementName
- {
- [Fx.Tag.SecurityNote(Critical = "Fetches the critical TopLevelElementName property.",
- Safe = "TopLevelElementName only needs to be protected for write.")]
- [SecuritySafeCritical]
- get { return helper.TopLevelElementName; }
- [Fx.Tag.SecurityNote(Critical = "Sets the critical TopLevelElementName property.")]
- [SecurityCritical]
- set { helper.TopLevelElementName = value; }
- }
- internal override XmlDictionaryString TopLevelElementNamespace
- {
- [Fx.Tag.SecurityNote(Critical = "Fetches the critical TopLevelElementNamespace property.",
- Safe = "TopLevelElementNamespace only needs to be protected for write.")]
- [SecuritySafeCritical]
- get { return helper.TopLevelElementNamespace; }
- [Fx.Tag.SecurityNote(Critical = "Sets the critical TopLevelElementNamespace property.")]
- [SecurityCritical]
- set { helper.TopLevelElementNamespace = value; }
- }
- internal bool IsTopLevelElementNullable
- {
- [Fx.Tag.SecurityNote(Critical = "Fetches the critical IsTopLevelElementNullable property.",
- Safe = "IsTopLevelElementNullable only needs to be protected for write.")]
- [SecuritySafeCritical]
- get { return helper.IsTopLevelElementNullable; }
- [Fx.Tag.SecurityNote(Critical = "Sets the critical IsTopLevelElementNullable property.")]
- [SecurityCritical]
- set { helper.IsTopLevelElementNullable = value; }
- }
- internal bool IsTypeDefinedOnImport
- {
- [Fx.Tag.SecurityNote(Critical = "Fetches the critical IsTypeDefinedOnImport property.",
- Safe = "IsTypeDefinedOnImport only needs to be protected for write.")]
- [SecuritySafeCritical]
- get { return helper.IsTypeDefinedOnImport; }
- [Fx.Tag.SecurityNote(Critical = "Sets the critical IsTypeDefinedOnImport property.")]
- [SecurityCritical]
- set { helper.IsTypeDefinedOnImport = value; }
- }
- internal CreateXmlSerializableDelegate CreateXmlSerializableDelegate
- {
- [Fx.Tag.SecurityNote(Critical = "Fetches the critical CreateXmlSerializableDelegate property.",
- Safe = "CreateXmlSerializableDelegate only needs to be protected for write; initialized in getter if null.")]
- [SecuritySafeCritical]
- get
- {
- if (helper.CreateXmlSerializableDelegate == null)
- {
- lock (this)
- {
- if (helper.CreateXmlSerializableDelegate == null)
- {
- CreateXmlSerializableDelegate tempCreateXmlSerializable = GenerateCreateXmlSerializableDelegate();
- Thread.MemoryBarrier();
- helper.CreateXmlSerializableDelegate = tempCreateXmlSerializable;
- }
- }
- }
- return helper.CreateXmlSerializableDelegate;
- }
- }
- internal override bool CanContainReferences
- {
- get { return false; }
- }
- internal override bool IsBuiltInDataContract
- {
- get
- {
- return UnderlyingType == Globals.TypeOfXmlElement || UnderlyingType == Globals.TypeOfXmlNodeArray;
- }
- }
- [Fx.Tag.SecurityNote(Critical = "Holds all state used for for (de)serializing XML types."
- + " Since the data is cached statically, we lock down access to it.")]
- #if !NO_SECURITY_ATTRIBUTES
- [SecurityCritical(SecurityCriticalScope.Everything)]
- #endif
- class XmlDataContractCriticalHelper : DataContract.DataContractCriticalHelper
- {
- DataContractDictionary knownDataContracts;
- bool isKnownTypeAttributeChecked;
- XmlDictionaryString topLevelElementName;
- XmlDictionaryString topLevelElementNamespace;
- bool isTopLevelElementNullable;
- bool isTypeDefinedOnImport;
- XmlSchemaType xsdType;
- bool hasRoot;
- CreateXmlSerializableDelegate createXmlSerializable;
- internal XmlDataContractCriticalHelper()
- {
- }
- internal XmlDataContractCriticalHelper(Type type)
- : base(type)
- {
- if (type.IsDefined(Globals.TypeOfDataContractAttribute, false))
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.IXmlSerializableCannotHaveDataContract, DataContract.GetClrTypeFullName(type))));
- if (type.IsDefined(Globals.TypeOfCollectionDataContractAttribute, false))
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.IXmlSerializableCannotHaveCollectionDataContract, DataContract.GetClrTypeFullName(type))));
- XmlSchemaType xsdType;
- bool hasRoot;
- XmlQualifiedName stableName;
- SchemaExporter.GetXmlTypeInfo(type, out stableName, out xsdType, out hasRoot);
- this.StableName = stableName;
- this.XsdType = xsdType;
- this.HasRoot = hasRoot;
- XmlDictionary dictionary = new XmlDictionary();
- this.Name = dictionary.Add(StableName.Name);
- this.Namespace = dictionary.Add(StableName.Namespace);
- object[] xmlRootAttributes = (UnderlyingType == null) ? null : UnderlyingType.GetCustomAttributes(Globals.TypeOfXmlRootAttribute, false);
- if (xmlRootAttributes == null || xmlRootAttributes.Length == 0)
- {
- if (hasRoot)
- {
- topLevelElementName = Name;
- topLevelElementNamespace = (this.StableName.Namespace == Globals.SchemaNamespace) ? DictionaryGlobals.EmptyString : Namespace;
- isTopLevelElementNullable = true;
- }
- }
- else
- {
- if (hasRoot)
- {
- XmlRootAttribute xmlRootAttribute = (XmlRootAttribute)xmlRootAttributes[0];
- isTopLevelElementNullable = xmlRootAttribute.IsNullable;
- string elementName = xmlRootAttribute.ElementName;
- topLevelElementName = (elementName == null || elementName.Length == 0) ? Name : dictionary.Add(DataContract.EncodeLocalName(elementName));
- string elementNs = xmlRootAttribute.Namespace;
- topLevelElementNamespace = (elementNs == null || elementNs.Length == 0) ? DictionaryGlobals.EmptyString : dictionary.Add(elementNs);
- }
- else
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.IsAnyCannotHaveXmlRoot, DataContract.GetClrTypeFullName(UnderlyingType))));
- }
- }
- }
- internal override DataContractDictionary KnownDataContracts
- {
- get
- {
- if (!isKnownTypeAttributeChecked && UnderlyingType != null)
- {
- lock (this)
- {
- if (!isKnownTypeAttributeChecked)
- {
- knownDataContracts = DataContract.ImportKnownTypeAttributes(this.UnderlyingType);
- Thread.MemoryBarrier();
- isKnownTypeAttributeChecked = true;
- }
- }
- }
- return knownDataContracts;
- }
- set { knownDataContracts = value; }
- }
- internal XmlSchemaType XsdType
- {
- get { return xsdType; }
- set { xsdType = value; }
- }
- internal bool IsAnonymous
- {
- get { return xsdType != null; }
- }
- internal override bool HasRoot
- {
- get { return hasRoot; }
- set { hasRoot = value; }
- }
- internal override XmlDictionaryString TopLevelElementName
- {
- get { return topLevelElementName; }
- set { topLevelElementName = value; }
- }
- internal override XmlDictionaryString TopLevelElementNamespace
- {
- get { return topLevelElementNamespace; }
- set { topLevelElementNamespace = value; }
- }
- internal bool IsTopLevelElementNullable
- {
- get { return isTopLevelElementNullable; }
- set { isTopLevelElementNullable = value; }
- }
- internal bool IsTypeDefinedOnImport
- {
- get { return isTypeDefinedOnImport; }
- set { isTypeDefinedOnImport = value; }
- }
- internal CreateXmlSerializableDelegate CreateXmlSerializableDelegate
- {
- get { return createXmlSerializable; }
- set { createXmlSerializable = value; }
- }
- }
- ConstructorInfo GetConstructor()
- {
- Type type = UnderlyingType;
- if (type.IsValueType)
- return null;
- ConstructorInfo ctor = type.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, Globals.EmptyTypeArray, null);
- if (ctor == null)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.IXmlSerializableMustHaveDefaultConstructor, DataContract.GetClrTypeFullName(type))));
- return ctor;
- }
- [Fx.Tag.SecurityNote(Critical = "Sets critical properties on XmlDataContract.")]
- [SecurityCritical]
- internal void SetTopLevelElementName(XmlQualifiedName elementName)
- {
- if (elementName != null)
- {
- XmlDictionary dictionary = new XmlDictionary();
- this.TopLevelElementName = dictionary.Add(elementName.Name);
- this.TopLevelElementNamespace = dictionary.Add(elementName.Namespace);
- }
- }
- #if !NO_DYNAMIC_CODEGEN
- [Fx.Tag.SecurityNote(Critical = "Calls CodeGenerator.BeginMethod which is SecurityCritical.",
- Safe = "Self-contained: returns the delegate to the generated IL but otherwise all IL generation is self-contained here.")]
- [SecuritySafeCritical]
- internal CreateXmlSerializableDelegate GenerateCreateXmlSerializableDelegate()
- {
- Type type = this.UnderlyingType;
- CodeGenerator ilg = new CodeGenerator();
- bool memberAccessFlag = RequiresMemberAccessForCreate(null);
- try
- {
- ilg.BeginMethod("Create" + DataContract.GetClrTypeFullName(type), typeof(CreateXmlSerializableDelegate), memberAccessFlag);
- }
- catch (SecurityException securityException)
- {
- if (memberAccessFlag && securityException.PermissionType.Equals(typeof(ReflectionPermission)))
- {
- RequiresMemberAccessForCreate(securityException);
- }
- else
- {
- throw;
- }
- }
- if (type.IsValueType)
- {
- System.Reflection.Emit.LocalBuilder local = ilg.DeclareLocal(type, type.Name + "Value");
- ilg.Ldloca(local);
- ilg.InitObj(type);
- ilg.Ldloc(local);
- }
- else
- {
- ilg.New(GetConstructor());
- }
- ilg.ConvertValue(this.UnderlyingType, Globals.TypeOfIXmlSerializable);
- ilg.Ret();
- return (CreateXmlSerializableDelegate)ilg.EndMethod();
- }
- #endif
- #if !NO_DYNAMIC_CODEGEN
- [Fx.Tag.SecurityNote(Miscellaneous = "RequiresReview - Calculates whether this Xml type requires MemberAccessPermission for deserialization."
- + " Since this information is used to determine whether to give the generated code access"
- + " permissions to private members, any changes to the logic should be reviewed.")]
- bool RequiresMemberAccessForCreate(SecurityException securityException)
- {
- if (!IsTypeVisible(UnderlyingType))
- {
- if (securityException != null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
- new SecurityException(SR.GetString(SR.PartialTrustIXmlSerializableTypeNotPublic, DataContract.GetClrTypeFullName(UnderlyingType)),
- securityException));
- }
- return true;
- }
- if (ConstructorRequiresMemberAccess(GetConstructor()))
- {
- if (securityException != null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
- new SecurityException(SR.GetString(SR.PartialTrustIXmlSerialzableNoPublicConstructor, DataContract.GetClrTypeFullName(UnderlyingType)),
- securityException));
- }
- return true;
- }
- return false;
- }
- #endif
- internal override bool Equals(object other, Dictionary<DataContractPairKey, object> checkedContracts)
- {
- if (IsEqualOrChecked(other, checkedContracts))
- return true;
- XmlDataContract dataContract = other as XmlDataContract;
- if (dataContract != null)
- {
- if (this.HasRoot != dataContract.HasRoot)
- return false;
- if (this.IsAnonymous)
- {
- return dataContract.IsAnonymous;
- }
- else
- {
- return (StableName.Name == dataContract.StableName.Name && StableName.Namespace == dataContract.StableName.Namespace);
- }
- }
- return false;
- }
- public override int GetHashCode()
- {
- return base.GetHashCode();
- }
- public override void WriteXmlValue(XmlWriterDelegator xmlWriter, object obj, XmlObjectSerializerWriteContext context)
- {
- if (context == null)
- XmlObjectSerializerWriteContext.WriteRootIXmlSerializable(xmlWriter, obj);
- else
- context.WriteIXmlSerializable(xmlWriter, obj);
- }
- public override object ReadXmlValue(XmlReaderDelegator xmlReader, XmlObjectSerializerReadContext context)
- {
- object o;
- if (context == null)
- {
- o = XmlObjectSerializerReadContext.ReadRootIXmlSerializable(xmlReader, this, true /*isMemberType*/);
- }
- else
- {
- o = context.ReadIXmlSerializable(xmlReader, this, true /*isMemberType*/);
- context.AddNewObject(o);
- }
- xmlReader.ReadEndElement();
- return o;
- }
- }
- }
|