System.Reflection.SecurityContextFrame.Push C# (CSharp) Method

Push() private method

private Push ( Assembly assembly ) : void
assembly Assembly
return void
        public extern void Push(Assembly assembly);

Usage Example

Esempio n. 1
0
        private unsafe static object[] GetCustomAttributes(
            RuntimeModule decoratedModule, int decoratedMetadataToken, int pcaCount, 
            RuntimeType attributeFilterType, bool mustBeInheritable, IList derivedAttributes, bool isDecoratedTargetSecurityTransparent)
        {
            if (decoratedModule.Assembly.ReflectionOnly)
                throw new InvalidOperationException(Environment.GetResourceString("Arg_ReflectionOnlyCA"));
            Contract.EndContractBlock();

            MetadataImport scope = decoratedModule.MetadataImport;
            CustomAttributeRecord[] car = CustomAttributeData.GetCustomAttributeRecords(decoratedModule, decoratedMetadataToken);

            bool useObjectArray = (attributeFilterType == null || attributeFilterType.IsValueType || attributeFilterType.ContainsGenericParameters);
            Type arrayType = useObjectArray ? typeof(object) : attributeFilterType;

            if (attributeFilterType == null && car.Length == 0)
                return CreateAttributeArrayHelper(arrayType, 0);

            object[] attributes = CreateAttributeArrayHelper(arrayType, car.Length);
            int cAttributes = 0;

            // Custom attribute security checks are done with respect to the assembly *decorated* with the 
            // custom attribute as opposed to the *caller of GetCustomAttributes*.
            // Since this assembly might not be on the stack and the attribute ctor or property setters we're about to invoke may
            // make security demands, we push a frame on the stack as a proxy for the decorated assembly (this frame will be picked
            // up an interpreted by the security stackwalker).
            // Once we push the frame it will be automatically popped in the event of an exception, so no need to use CERs or the
            // like.
            SecurityContextFrame frame = new SecurityContextFrame();
            frame.Push(decoratedModule.GetRuntimeAssembly());

            // Optimization for the case where attributes decorate entities in the same assembly in which case 
            // we can cache the successful APTCA check between the decorated and the declared assembly.
            Assembly lastAptcaOkAssembly = null;

            for (int i = 0; i < car.Length; i++)
            {
                object attribute = null;
                CustomAttributeRecord caRecord = car[i];

                IRuntimeMethodInfo ctor = null;
                RuntimeType attributeType = null;
                bool ctorHasParameters, isVarArg;
                int cNamedArgs = 0;

                IntPtr blobStart = caRecord.blob.Signature;
                IntPtr blobEnd = (IntPtr)((byte*)blobStart + caRecord.blob.Length);
                int blobLen = (int)((byte*)blobEnd - (byte*)blobStart);

                if (!FilterCustomAttributeRecord(caRecord, scope, ref lastAptcaOkAssembly, 
                                                 decoratedModule, decoratedMetadataToken, attributeFilterType, mustBeInheritable, 
                                                 attributes, derivedAttributes,
                                                 out attributeType, out ctor, out ctorHasParameters, out isVarArg))
                    continue;

                if (ctor != null)
                {
                    // Linktime demand checks 
                    // decoratedMetadataToken needed as it may be "transparent" in which case we do a full stack walk
                    RuntimeMethodHandle.CheckLinktimeDemands(ctor, decoratedModule, isDecoratedTargetSecurityTransparent);
                }
                else
                {

                }

                // Leverage RuntimeConstructorInfo standard .ctor verfication
                RuntimeConstructorInfo.CheckCanCreateInstance(attributeType, isVarArg); 

                // Create custom attribute object
                if (ctorHasParameters)
                {
                    attribute = CreateCaObject(decoratedModule, ctor, ref blobStart, blobEnd, out cNamedArgs); 
                }
                else
                {
                    attribute = RuntimeTypeHandle.CreateCaInstance(attributeType, ctor);

                    // It is allowed by the ECMA spec to have an empty signature blob
                    if (blobLen == 0)
                        cNamedArgs = 0;
                    else
                    {
                        // Metadata is always written in little-endian format. Must account for this on
                        // big-endian platforms.
#if BIGENDIAN
                        const int CustomAttributeVersion = 0x0100;
#else
                        const int CustomAttributeVersion = 0x0001;
#endif
                        if (Marshal.ReadInt16(blobStart) != CustomAttributeVersion)
                            throw new CustomAttributeFormatException();
                        blobStart = (IntPtr)((byte*)blobStart + 2); // skip version prefix

                        cNamedArgs = Marshal.ReadInt16(blobStart);
                        blobStart = (IntPtr)((byte*)blobStart + 2); // skip namedArgs count
#if BIGENDIAN
                        cNamedArgs = ((cNamedArgs & 0xff00) >> 8) | ((cNamedArgs & 0x00ff) << 8);
#endif
                    }
                }

                for (int j = 0; j < cNamedArgs; j++)
                {
                    #region // Initialize named properties and fields
                    string name;
                    bool isProperty;
                    RuntimeType type;
                    object value;
                    
                    IntPtr blobItr = caRecord.blob.Signature;

                    GetPropertyOrFieldData(decoratedModule, ref blobStart, blobEnd, out name, out isProperty, out type, out value);

                    try
                    {
                        if (isProperty)
                        {
                            #region // Initialize property
                            if (type == null && value != null)
                            {
                                type = (RuntimeType)value.GetType();
                                if (type == Type_RuntimeType)
                                    type = Type_Type;
                            }

                            RuntimePropertyInfo property = null;

                            if (type == null)
                                property = attributeType.GetProperty(name) as RuntimePropertyInfo;
                            else
                                property = attributeType.GetProperty(name, type, Type.EmptyTypes) as RuntimePropertyInfo;

                            // Did we get a valid property reference?
                            if (property == null)
                            {
                                throw new CustomAttributeFormatException(
                                    String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString(
                                        isProperty ? "RFLCT.InvalidPropFail" : "RFLCT.InvalidFieldFail"), name));
                            }

                            RuntimeMethodInfo setMethod = property.GetSetMethod(true) as RuntimeMethodInfo;
                            
                            // Public properties may have non-public setter methods
                            if (!setMethod.IsPublic)
                                continue;

                            RuntimeMethodHandle.CheckLinktimeDemands(setMethod, decoratedModule, isDecoratedTargetSecurityTransparent);

                            setMethod.UnsafeInvoke(attribute, BindingFlags.Default, null, new object[] { value }, null);
                            #endregion
                        }
                        else
                        {
                            RtFieldInfo field = attributeType.GetField(name) as RtFieldInfo;

                            if (isDecoratedTargetSecurityTransparent)
                            {
                                RuntimeFieldHandle.CheckAttributeAccess(field.FieldHandle, decoratedModule.GetNativeHandle());
                            }

                            field.CheckConsistency(attribute);
                            field.UnsafeSetValue(attribute, value, BindingFlags.Default, Type.DefaultBinder, null);
                        }
                    }
                    catch (Exception e)
                    {
                        throw new CustomAttributeFormatException(
                            String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString(
                                isProperty ? "RFLCT.InvalidPropFail" : "RFLCT.InvalidFieldFail"), name), e);
                    }
                    #endregion
                }

                if (!blobStart.Equals(blobEnd))
                    throw new CustomAttributeFormatException();

                attributes[cAttributes++] = attribute;
            }

            // The frame will be popped automatically if we take an exception any time after we pushed it. So no need of a catch or
            // finally or CERs here.
            frame.Pop();

            if (cAttributes == car.Length && pcaCount == 0)
                return attributes;

            object[] result = CreateAttributeArrayHelper(arrayType, cAttributes + pcaCount);
            Array.Copy(attributes, 0, result, 0, cAttributes);
            return result;
        }
All Usage Examples Of System.Reflection.SecurityContextFrame::Push
SecurityContextFrame