Ejemplo n.º 1
0
 //
 // This entry is targeted by the ILTransformer to implement Type.GetType()'s ability to detect the calling assembly and use it as
 // a default assembly name.
 //
 public static Type GetType(String typeName, String callingAssemblyName, bool throwOnError, bool ignoreCase)
 {
     LowLevelListWithIList<String> defaultAssemblies = new LowLevelListWithIList<String>();
     defaultAssemblies.Add(callingAssemblyName);
     defaultAssemblies.AddRange(DefaultAssemblyNamesForGetType);
     return ReflectionCoreExecution.ExecutionDomain.GetType(typeName, throwOnError, ignoreCase, defaultAssemblies);
 }
Ejemplo n.º 2
0
 //
 // This entry is targeted by the ILTransformer to implement Type.GetType()'s ability to detect the calling assembly and use it as
 // a default assembly name.
 //
 public static Type ExtensibleGetType(string typeName, string callingAssemblyName, Func<AssemblyName, Assembly> assemblyResolver, Func<Assembly, string, bool, Type> typeResolver, bool throwOnError, bool ignoreCase)
 {
     LowLevelListWithIList<String> defaultAssemblies = new LowLevelListWithIList<String>();
     defaultAssemblies.Add(callingAssemblyName);
     defaultAssemblies.AddRange(DefaultAssemblyNamesForGetType);
     return ReflectionCoreExecution.ExecutionDomain.GetType(typeName, assemblyResolver, typeResolver, throwOnError, ignoreCase, defaultAssemblies);
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Convert each Oid's value to an ASCII string, then create an unmanaged array of "numOids" LPSTR pointers, one for each Oid.
        /// "numOids" is the number of LPSTR pointers. This is normally the same as oids.Count, except in the case where a malicious caller
        /// appends to the OidCollection while this method is in progress. In such a case, this method guarantees only that this won't create
        /// an unmanaged buffer overflow condition.
        /// </summary>
        public static SafeHandle ToLpstrArray(this OidCollection oids, out int numOids)
        {
            if (oids == null || oids.Count == 0)
            {
                numOids = 0;
                return SafeLocalAllocHandle.InvalidHandle;
            }

            // Copy the oid strings to a local list to prevent a security race condition where
            // the OidCollection or individual oids can be modified by another thread and
            // potentially cause a buffer overflow
            LowLevelListWithIList<byte[]> oidStrings = new LowLevelListWithIList<byte[]>();
            foreach (Oid oid in oids)
            {
                byte[] oidString = oid.ValueAsAscii();
                oidStrings.Add(oidString);
            }

            numOids = oidStrings.Count;
            unsafe
            {
                int allocationSize = checked(numOids * sizeof(void*));
                foreach (byte[] oidString in oidStrings)
                {
                    checked
                    {
                        allocationSize += oidString.Length + 1;
                    }
                }

                SafeLocalAllocHandle safeLocalAllocHandle = SafeLocalAllocHandle.Create(allocationSize);
                byte** pOidPointers = (byte**)(safeLocalAllocHandle.DangerousGetHandle());
                byte* pOidContents = (byte*)(pOidPointers + numOids);

                for (int i = 0; i < numOids; i++)
                {
                    pOidPointers[i] = pOidContents;
                    byte[] oidString = oidStrings[i];
                    Marshal.Copy(oidString, 0, new IntPtr(pOidContents), oidString.Length);
                    pOidContents[oidString.Length] = 0;
                    pOidContents += oidString.Length + 1;
                }

                return safeLocalAllocHandle;
            }
        }
Ejemplo n.º 4
0
        //
        // Foo or Foo+Inner or Foo[String] or Foo+Inner[String]
        //
        private NonQualifiedTypeName ParseNamedOrConstructedGenericTypeName()
        {
            NamedTypeName namedType = ParseNamedTypeName();
            // Because "[" is used both for generic arguments and array indexes, we must peek two characters deep.
            if (!(_lexer.Peek == TokenType.OpenSqBracket && (_lexer.PeekSecond == TokenType.Other || _lexer.PeekSecond == TokenType.OpenSqBracket)))
                return namedType;
            else
            {
                _lexer.Skip();
                LowLevelListWithIList<TypeName> genericTypeArguments = new LowLevelListWithIList<TypeName>();
                for (;;)
                {
                    TypeName genericTypeArgument = ParseGenericTypeArgument();
                    genericTypeArguments.Add(genericTypeArgument);
                    TokenType token = _lexer.GetNextToken();
                    if (token == TokenType.CloseSqBracket)
                        break;
                    if (token != TokenType.Comma)
                        throw new ArgumentException();
                }

                return new ConstructedGenericTypeName(namedType, genericTypeArguments);
            }
        }
        //
        // If throwIfMissingMetadata is false, returns null rather than throwing a MissingMetadataException.
        //
        internal sealed override IList<CustomAttributeTypedArgument> GetConstructorArguments(bool throwIfMissingMetadata)
        {
            int index = 0;
            LowLevelList<Handle> lazyCtorTypeHandles = null;
            LowLevelListWithIList<CustomAttributeTypedArgument> customAttributeTypedArguments = new LowLevelListWithIList<CustomAttributeTypedArgument>();

            foreach (FixedArgumentHandle fixedArgumentHandle in _customAttribute.FixedArguments)
            {
                CustomAttributeTypedArgument customAttributeTypedArgument =
                    ParseFixedArgument(
                        _reader,
                        fixedArgumentHandle,
                        throwIfMissingMetadata,
                        delegate ()
                        {
                            // If we got here, the custom attribute blob lacked type information (this is actually the typical case.) We must fallback to
                            // parsing the constructor's signature to get the type info. 
                            if (lazyCtorTypeHandles == null)
                            {
                                IEnumerable<ParameterTypeSignatureHandle> parameterTypeSignatureHandles;
                                HandleType handleType = _customAttribute.Constructor.HandleType;
                                switch (handleType)
                                {
                                    case HandleType.QualifiedMethod:
                                        parameterTypeSignatureHandles = _customAttribute.Constructor.ToQualifiedMethodHandle(_reader).GetQualifiedMethod(_reader).Method.GetMethod(_reader).Signature.GetMethodSignature(_reader).Parameters;
                                        break;

                                    case HandleType.MemberReference:
                                        parameterTypeSignatureHandles = _customAttribute.Constructor.ToMemberReferenceHandle(_reader).GetMemberReference(_reader).Signature.ToMethodSignatureHandle(_reader).GetMethodSignature(_reader).Parameters;
                                        break;
                                    default:
                                        throw new BadImageFormatException();
                                }
                                LowLevelList<Handle> ctorTypeHandles = new LowLevelList<Handle>();
                                foreach (ParameterTypeSignatureHandle parameterTypeSignatureHandle in parameterTypeSignatureHandles)
                                {
                                    ctorTypeHandles.Add(parameterTypeSignatureHandle.GetParameterTypeSignature(_reader).Type);
                                }
                                lazyCtorTypeHandles = ctorTypeHandles;
                            }
                            Handle typeHandle = lazyCtorTypeHandles[index];
                            Exception exception = null;
                            RuntimeType argumentType = _reflectionDomain.TryResolve(_reader, typeHandle, new TypeContext(null, null), ref exception);
                            if (argumentType == null)
                            {
                                if (throwIfMissingMetadata)
                                    throw exception;
                                return null;
                            }
                            return argumentType;
                        }
                );

                if (customAttributeTypedArgument.ArgumentType == null)
                {
                    Debug.Assert(!throwIfMissingMetadata);
                    return null;
                }

                customAttributeTypedArguments.Add(customAttributeTypedArgument);
                index++;
            }

            return customAttributeTypedArguments;
        }
        //
        // Wrap a custom attribute argument (or an element of an array-typed custom attribute argument) in a CustomAttributeTypeArgument structure
        // for insertion into a CustomAttributeData value.
        //
        private CustomAttributeTypedArgument WrapInCustomAttributeTypedArgument(Object value, Type argumentType)
        {
            // To support reflection domains other than the execution domain, we'll have to translate argumentType to one of the values off
            // _reflectionDomain.FoundationTypes rather than using the direct value of value.GetType(). It's unclear how to do this for 
            // enum types. Cross that bridge if ever get to it. 
            Debug.Assert(_reflectionDomain is ExecutionDomain);

            if (argumentType.Equals(typeof(Object)))
            {
                // If the declared attribute type is System.Object, we must report the type based on the runtime value.
                if (value == null)
                    argumentType = typeof(String);  // Why is null reported as System.String? Because that's what the desktop CLR does.
                else if (value is Type)
                    argumentType = typeof(Type);    // value.GetType() will not actually be System.Type - rather it will be some internal implementation type. We only want to report it as System.Type.
                else
                    argumentType = value.GetType();
            }

            Array arrayValue = value as Array;
            if (arrayValue != null)
            {
                if (!argumentType.IsArray)
                    throw new BadImageFormatException();
                Type reportedElementType = argumentType.GetElementType();
                LowLevelListWithIList<CustomAttributeTypedArgument> elementTypedArguments = new LowLevelListWithIList<CustomAttributeTypedArgument>();
                foreach (Object elementValue in arrayValue)
                {
                    CustomAttributeTypedArgument elementTypedArgument = WrapInCustomAttributeTypedArgument(elementValue, reportedElementType);
                    elementTypedArguments.Add(elementTypedArgument);
                }
                return ExtensibleCustomAttributeData.CreateCustomAttributeTypedArgument(argumentType, new ReadOnlyCollection<CustomAttributeTypedArgument>(elementTypedArguments));
            }
            else
            {
                return ExtensibleCustomAttributeData.CreateCustomAttributeTypedArgument(argumentType, value);
            }
        }
 //
 // If throwIfMissingMetadata is false, returns null rather than throwing a MissingMetadataException.
 //
 internal sealed override IList<CustomAttributeNamedArgument> GetNamedArguments(bool throwIfMissingMetadata)
 {
     LowLevelListWithIList<CustomAttributeNamedArgument> customAttributeNamedArguments = new LowLevelListWithIList<CustomAttributeNamedArgument>();
     foreach (NamedArgumentHandle namedArgumentHandle in _customAttribute.NamedArguments)
     {
         NamedArgument namedArgument = namedArgumentHandle.GetNamedArgument(_reader);
         String memberName = namedArgument.Name.GetString(_reader);
         bool isField = (namedArgument.Flags == NamedArgumentMemberKind.Field);
         CustomAttributeTypedArgument typedValue =
             ParseFixedArgument(
                 _reader,
                 namedArgument.Value,
                 throwIfMissingMetadata,
                 delegate ()
                 {
                     // We got here because the custom attribute blob did not inclue type information. For named arguments, this is considered illegal metadata
                     // (ECMA always includes type info for named arguments.)
                     throw new BadImageFormatException();
                 }
         );
         if (typedValue.ArgumentType == null)
         {
             Debug.Assert(!throwIfMissingMetadata);
             return null;
         }
         customAttributeNamedArguments.Add(ExtensibleCustomAttributeData.CreateCustomAttributeNamedArgument(this.AttributeType, memberName, isField, typedValue));
     }
     return customAttributeNamedArguments;
 }
        //
        // Wrap a custom attribute argument (or an element of an array-typed custom attribute argument) in a CustomAttributeTypeArgument structure
        // for insertion into a CustomAttributeData value.
        //
        private CustomAttributeTypedArgument WrapInCustomAttributeTypedArgument(Object value, Type argumentType)
        {
            if (argumentType.Equals(typeof(Object)))
            {
                // If the declared attribute type is System.Object, we must report the type based on the runtime value.
                if (value == null)
                    argumentType = typeof(String);  // Why is null reported as System.String? Because that's what the desktop CLR does.
                else if (value is Type)
                    argumentType = typeof(Type);    // value.GetType() will not actually be System.Type - rather it will be some internal implementation type. We only want to report it as System.Type.
                else
                    argumentType = value.GetType();
            }

            // Handle the array case
            IEnumerable enumerableValue = value as IEnumerable;
            if (enumerableValue != null && !(value is String))
            {
                if (!argumentType.IsArray)
                    throw new BadImageFormatException();
                Type reportedElementType = argumentType.GetElementType();
                LowLevelListWithIList<CustomAttributeTypedArgument> elementTypedArguments = new LowLevelListWithIList<CustomAttributeTypedArgument>();
                foreach (Object elementValue in enumerableValue)
                {
                    CustomAttributeTypedArgument elementTypedArgument = WrapInCustomAttributeTypedArgument(elementValue, reportedElementType);
                    elementTypedArguments.Add(elementTypedArgument);
                }
                return new CustomAttributeTypedArgument(argumentType, new ReadOnlyCollection<CustomAttributeTypedArgument>(elementTypedArguments));
            }
            else
            {
                return new CustomAttributeTypedArgument(argumentType, value);
            }
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Flattens an <see cref="AggregateException"/> instances into a single, new instance.
        /// </summary>
        /// <returns>A new, flattened <see cref="AggregateException"/>.</returns>
        /// <remarks>
        /// If any inner exceptions are themselves instances of
        /// <see cref="AggregateException"/>, this method will recursively flatten all of them. The
        /// inner exceptions returned in the new <see cref="AggregateException"/>
        /// will be the union of all of the the inner exceptions from exception tree rooted at the provided
        /// <see cref="AggregateException"/> instance.
        /// </remarks>
        public AggregateException Flatten()
        {
            // Initialize a collection to contain the flattened exceptions.
            LowLevelListWithIList<Exception> flattenedExceptions = new LowLevelListWithIList<Exception>();

            // Create a list to remember all aggregates to be flattened, this will be accessed like a FIFO queue
            LowLevelList<AggregateException> exceptionsToFlatten = new LowLevelList<AggregateException>();
            exceptionsToFlatten.Add(this);
            int nDequeueIndex = 0;

            // Continue removing and recursively flattening exceptions, until there are no more.
            while (exceptionsToFlatten.Count > nDequeueIndex)
            {
                // dequeue one from exceptionsToFlatten
                IList<Exception> currentInnerExceptions = exceptionsToFlatten[nDequeueIndex++].InnerExceptions;

                for (int i = 0; i < currentInnerExceptions.Count; i++)
                {
                    Exception currentInnerException = currentInnerExceptions[i];

                    if (currentInnerException == null)
                    {
                        continue;
                    }

                    AggregateException currentInnerAsAggregate = currentInnerException as AggregateException;

                    // If this exception is an aggregate, keep it around for later.  Otherwise,
                    // simply add it to the list of flattened exceptions to be returned.
                    if (currentInnerAsAggregate != null)
                    {
                        exceptionsToFlatten.Add(currentInnerAsAggregate);
                    }
                    else
                    {
                        flattenedExceptions.Add(currentInnerException);
                    }
                }
            }


            return new AggregateException(Message, flattenedExceptions);
        }
        public override Object InvokeMember(
            String name, BindingFlags bindingFlags, Binder binder, Object target,
            Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)
        {
            const BindingFlags MemberBindingMask = (BindingFlags)0x000000FF;
            const BindingFlags InvocationMask = (BindingFlags)0x0000FF00;
            const BindingFlags BinderGetSetProperty = BindingFlags.GetProperty | BindingFlags.SetProperty;
            const BindingFlags BinderGetSetField = BindingFlags.GetField | BindingFlags.SetField;
            const BindingFlags BinderNonFieldGetSet = (BindingFlags)0x00FFF300;
            const BindingFlags BinderNonCreateInstance = BindingFlags.InvokeMethod | BinderGetSetField | BinderGetSetProperty;

            if (IsGenericParameter)
                throw new InvalidOperationException(SR.Arg_GenericParameter);

            #region Preconditions
            if ((bindingFlags & InvocationMask) == 0)
                // "Must specify binding flags describing the invoke operation required."
                throw new ArgumentException(SR.Arg_NoAccessSpec, nameof(bindingFlags));

            // Provide a default binding mask if none is provided 
            if ((bindingFlags & MemberBindingMask) == 0)
            {
                bindingFlags |= BindingFlags.Instance | BindingFlags.Public;

                if ((bindingFlags & BindingFlags.CreateInstance) == 0)
                    bindingFlags |= BindingFlags.Static;
            }

            // There must not be more named parameters than provided arguments
            if (namedParams != null)
            {
                if (providedArgs != null)
                {
                    if (namedParams.Length > providedArgs.Length)
                        // "Named parameter array can not be bigger than argument array."
                        throw new ArgumentException(SR.Arg_NamedParamTooBig, nameof(namedParams));
                }
                else
                {
                    if (namedParams.Length != 0)
                        // "Named parameter array can not be bigger than argument array."
                        throw new ArgumentException(SR.Arg_NamedParamTooBig, nameof(namedParams));
                }
            }
            #endregion

            #region COM Interop
            if (target != null && target.GetType().IsCOMObject)
                throw new PlatformNotSupportedException(SR.Arg_PlatformNotSupportedInvokeMemberCom);
            #endregion

            #region Check that any named paramters are not null
            if (namedParams != null && Array.IndexOf(namedParams, null) != -1)
                // "Named parameter value must not be null."
                throw new ArgumentException(SR.Arg_NamedParamNull, nameof(namedParams));
            #endregion

            int argCnt = (providedArgs != null) ? providedArgs.Length : 0;

            #region Get a Binder
            if (binder == null)
                binder = DefaultBinder;

            bool bDefaultBinder = (binder == DefaultBinder);
            #endregion

            #region Delegate to Activator.CreateInstance
            if ((bindingFlags & BindingFlags.CreateInstance) != 0)
            {
                if ((bindingFlags & BindingFlags.CreateInstance) != 0 && (bindingFlags & BinderNonCreateInstance) != 0)
                    // "Can not specify both CreateInstance and another access type."
                    throw new ArgumentException(SR.Arg_CreatInstAccess, nameof(bindingFlags));

                return Activator.CreateInstance(this, bindingFlags, binder, providedArgs, culture);
            }
            #endregion

            // PutDispProperty and\or PutRefDispProperty ==> SetProperty.
            if ((bindingFlags & (BindingFlags.PutDispProperty | BindingFlags.PutRefDispProperty)) != 0)
                bindingFlags |= BindingFlags.SetProperty;

            #region Name
            if (name == null)
                throw new ArgumentNullException(nameof(name));

            if (name.Length == 0 || name.Equals(@"[DISPID=0]"))
            {
                name = GetDefaultMemberName();

                if (name == null)
                {
                    // in InvokeMember we always pretend there is a default member if none is provided and we make it ToString
                    name = "ToString";
                }
            }
            #endregion

            #region GetField or SetField
            bool IsGetField = (bindingFlags & BindingFlags.GetField) != 0;
            bool IsSetField = (bindingFlags & BindingFlags.SetField) != 0;

            if (IsGetField || IsSetField)
            {
                #region Preconditions
                if (IsGetField)
                {
                    if (IsSetField)
                        // "Can not specify both Get and Set on a field."
                        throw new ArgumentException(SR.Arg_FldSetGet, nameof(bindingFlags));

                    if ((bindingFlags & BindingFlags.SetProperty) != 0)
                        // "Can not specify both GetField and SetProperty."
                        throw new ArgumentException(SR.Arg_FldGetPropSet, nameof(bindingFlags));
                }
                else
                {
                    Debug.Assert(IsSetField);

                    if (providedArgs == null)
                        throw new ArgumentNullException(nameof(providedArgs));

                    if ((bindingFlags & BindingFlags.GetProperty) != 0)
                        // "Can not specify both SetField and GetProperty."
                        throw new ArgumentException(SR.Arg_FldSetPropGet, nameof(bindingFlags));

                    if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
                        // "Can not specify Set on a Field and Invoke on a method."
                        throw new ArgumentException(SR.Arg_FldSetInvoke, nameof(bindingFlags));
                }
                #endregion

                #region Lookup Field
                FieldInfo selFld = null;
                FieldInfo[] flds = GetMember(name, MemberTypes.Field, bindingFlags) as FieldInfo[];

                Debug.Assert(flds != null);

                if (flds.Length == 1)
                {
                    selFld = flds[0];
                }
                else if (flds.Length > 0)
                {
                    selFld = binder.BindToField(bindingFlags, flds, IsGetField ? Empty.Value : providedArgs[0], culture);
                }
                #endregion

                if (selFld != null)
                {
                    #region Invocation on a field
                    if (selFld.FieldType.IsArray || Object.ReferenceEquals(selFld.FieldType, CommonRuntimeTypes.Array))
                    {
                        #region Invocation of an array Field
                        int idxCnt;

                        if ((bindingFlags & BindingFlags.GetField) != 0)
                        {
                            idxCnt = argCnt;
                        }
                        else
                        {
                            idxCnt = argCnt - 1;
                        }

                        if (idxCnt > 0)
                        {
                            // Verify that all of the index values are ints
                            int[] idx = new int[idxCnt];
                            for (int i = 0; i < idxCnt; i++)
                            {
                                try
                                {
                                    idx[i] = ((IConvertible)providedArgs[i]).ToInt32(null);
                                }
                                catch (InvalidCastException)
                                {
                                    throw new ArgumentException(SR.Arg_IndexMustBeInt);
                                }
                            }

                            // Set or get the value...
                            Array a = (Array)selFld.GetValue(target);

                            // Set or get the value in the array
                            if ((bindingFlags & BindingFlags.GetField) != 0)
                            {
                                return a.GetValue(idx);
                            }
                            else
                            {
                                a.SetValue(providedArgs[idxCnt], idx);
                                return null;
                            }
                        }
                        #endregion
                    }

                    if (IsGetField)
                    {
                        #region Get the field value
                        if (argCnt != 0)
                            throw new ArgumentException(SR.Arg_FldGetArgErr, nameof(bindingFlags));

                        return selFld.GetValue(target);
                        #endregion
                    }
                    else
                    {
                        #region Set the field Value
                        if (argCnt != 1)
                            throw new ArgumentException(SR.Arg_FldSetArgErr, nameof(bindingFlags));

                        selFld.SetValue(target, providedArgs[0], bindingFlags, binder, culture);

                        return null;
                        #endregion
                    }
                    #endregion
                }

                if ((bindingFlags & BinderNonFieldGetSet) == 0)
                    throw new MissingFieldException(FullName, name);
            }
            #endregion                    

            #region Property PreConditions
            // @Legacy - This is RTM behavior
            bool isGetProperty = (bindingFlags & BindingFlags.GetProperty) != 0;
            bool isSetProperty = (bindingFlags & BindingFlags.SetProperty) != 0;

            if (isGetProperty || isSetProperty)
            {
                #region Preconditions
                if (isGetProperty)
                {
                    Debug.Assert(!IsSetField);

                    if (isSetProperty)
                        throw new ArgumentException(SR.Arg_PropSetGet, nameof(bindingFlags));
                }
                else
                {
                    Debug.Assert(isSetProperty);

                    Debug.Assert(!IsGetField);

                    if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
                        throw new ArgumentException(SR.Arg_PropSetInvoke, nameof(bindingFlags));
                }
                #endregion
            }
            #endregion

            MethodInfo[] finalists = null;
            MethodInfo finalist = null;

            #region BindingFlags.InvokeMethod
            if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
            {
                #region Lookup Methods
                MethodInfo[] semiFinalists = GetMember(name, MemberTypes.Method, bindingFlags) as MethodInfo[];
                LowLevelListWithIList<MethodInfo> results = null;

                for (int i = 0; i < semiFinalists.Length; i++)
                {
                    MethodInfo semiFinalist = semiFinalists[i];
                    Debug.Assert(semiFinalist != null);

                    if (!semiFinalist.QualifiesBasedOnParameterCount(bindingFlags, CallingConventions.Any, new Type[argCnt]))
                        continue;

                    if (finalist == null)
                    {
                        finalist = semiFinalist;
                    }
                    else
                    {
                        if (results == null)
                        {
                            results = new LowLevelListWithIList<MethodInfo>(semiFinalists.Length);
                            results.Add(finalist);
                        }

                        results.Add(semiFinalist);
                    }
                }

                if (results != null)
                {
                    Debug.Assert(results.Count > 1);
                    finalists = new MethodInfo[results.Count];
                    results.CopyTo(finalists, 0);
                }
                #endregion
            }
            #endregion

            Debug.Assert(finalists == null || finalist != null);

            #region BindingFlags.GetProperty or BindingFlags.SetProperty
            if (finalist == null && isGetProperty || isSetProperty)
            {
                #region Lookup Property
                PropertyInfo[] semiFinalists = GetMember(name, MemberTypes.Property, bindingFlags) as PropertyInfo[];
                LowLevelListWithIList<MethodInfo> results = null;

                for (int i = 0; i < semiFinalists.Length; i++)
                {
                    MethodInfo semiFinalist = null;

                    if (isSetProperty)
                    {
                        semiFinalist = semiFinalists[i].GetSetMethod(true);
                    }
                    else
                    {
                        semiFinalist = semiFinalists[i].GetGetMethod(true);
                    }

                    if (semiFinalist == null)
                        continue;

                    BindingFlags expectedBindingFlags = semiFinalist.IsPublic ? BindingFlags.Public : BindingFlags.NonPublic;
                    if ((bindingFlags & expectedBindingFlags) != expectedBindingFlags)
                        continue;

                    if (!semiFinalist.QualifiesBasedOnParameterCount(bindingFlags, CallingConventions.Any, new Type[argCnt]))
                        continue;

                    if (finalist == null)
                    {
                        finalist = semiFinalist;
                    }
                    else
                    {
                        if (results == null)
                        {
                            results = new LowLevelListWithIList<MethodInfo>(semiFinalists.Length);
                            results.Add(finalist);
                        }

                        results.Add(semiFinalist);
                    }
                }

                if (results != null)
                {
                    Debug.Assert(results.Count > 1);
                    finalists = new MethodInfo[results.Count];
                    results.CopyTo(finalists, 0);
                }
                #endregion            
            }
            #endregion

            if (finalist != null)
            {
                #region Invoke
                if (finalists == null &&
                    argCnt == 0 &&
                    finalist.GetParametersNoCopy().Length == 0 &&
                    (bindingFlags & BindingFlags.OptionalParamBinding) == 0)
                {
                    //if (useCache && argCnt == props[0].GetParameters().Length)
                    //    AddMethodToCache(name, bindingFlags, argCnt, providedArgs, props[0]);

                    return finalist.Invoke(target, bindingFlags, binder, providedArgs, culture);
                }

                if (finalists == null)
                    finalists = new MethodInfo[] { finalist };

                if (providedArgs == null)
                    providedArgs = Array.Empty<object>();

                Object state = null;


                MethodBase invokeMethod = null;

                try { invokeMethod = binder.BindToMethod(bindingFlags, finalists, ref providedArgs, modifiers, culture, namedParams, out state); }
                catch (MissingMethodException) { }

                if (invokeMethod == null)
                    throw new MissingMethodException(FullName, name);

                //if (useCache && argCnt == invokeMethod.GetParameters().Length)
                //    AddMethodToCache(name, bindingFlags, argCnt, providedArgs, invokeMethod);

                Object result = ((MethodInfo)invokeMethod).Invoke(target, bindingFlags, binder, providedArgs, culture);

                if (state != null)
                    binder.ReorderArgumentArray(ref providedArgs, state);

                return result;
                #endregion
            }

            throw new MissingMethodException(FullName, name);
        }
Ejemplo n.º 11
0
        /// <summary>
        /// This callback gets called whenever a module gets registered. It adds the metadata reader
        /// for the new module to the available scopes. The lock in ExecutionEnvironmentImplementation ensures
        /// that this function may never be called concurrently so that we can assume that two threads
        /// never update the reader and scope list at the same time.
        /// </summary>
        /// <param name="moduleHandle">Module handle to register</param>
        private void RegisterModule(IntPtr moduleHandle)
        {
            MetadataReader newReader = _executionEnvironment.GetMetadataReaderForModule(moduleHandle);
            if (newReader == null)
            {
                return;
            }

            // Build new reader list
            LowLevelListWithIList<MetadataReader> readers = new LowLevelListWithIList<MetadataReader>(_readers.Count + 1);
            foreach (MetadataReader oldReader in _readers)
            {
                readers.Add(oldReader);
            }
            readers.Add(newReader);

            LowLevelDictionaryWithIEnumerable<string, ScopeDefinitionGroup> scopeGroups = new LowLevelDictionaryWithIEnumerable<string, ScopeDefinitionGroup>();
            foreach (KeyValuePair<string, ScopeDefinitionGroup> oldGroup in _scopeGroups)
            {
                scopeGroups.Add(oldGroup.Key, oldGroup.Value);
            }
            AddScopesFromReaderToGroups(scopeGroups, newReader);

            // Update reader and scope list
            _readers = readers;
            _scopeGroups = scopeGroups;
        }
Ejemplo n.º 12
0
        public override Object InvokeMember(
            String name, BindingFlags bindingFlags, Binder binder, Object target,
            Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)
        {
            const BindingFlags MemberBindingMask       = (BindingFlags)0x000000FF;
            const BindingFlags InvocationMask          = (BindingFlags)0x0000FF00;
            const BindingFlags BinderGetSetProperty    = BindingFlags.GetProperty | BindingFlags.SetProperty;
            const BindingFlags BinderGetSetField       = BindingFlags.GetField | BindingFlags.SetField;
            const BindingFlags BinderNonFieldGetSet    = (BindingFlags)0x00FFF300;
            const BindingFlags BinderNonCreateInstance = BindingFlags.InvokeMethod | BinderGetSetField | BinderGetSetProperty;

            if (IsGenericParameter)
            {
                throw new InvalidOperationException(SR.Arg_GenericParameter);
            }

            #region Preconditions
            if ((bindingFlags & InvocationMask) == 0)
            {
                // "Must specify binding flags describing the invoke operation required."
                throw new ArgumentException(SR.Arg_NoAccessSpec, nameof(bindingFlags));
            }

            // Provide a default binding mask if none is provided
            if ((bindingFlags & MemberBindingMask) == 0)
            {
                bindingFlags |= BindingFlags.Instance | BindingFlags.Public;

                if ((bindingFlags & BindingFlags.CreateInstance) == 0)
                {
                    bindingFlags |= BindingFlags.Static;
                }
            }

            // There must not be more named parameters than provided arguments
            if (namedParams != null)
            {
                if (providedArgs != null)
                {
                    if (namedParams.Length > providedArgs.Length)
                    {
                        // "Named parameter array can not be bigger than argument array."
                        throw new ArgumentException(SR.Arg_NamedParamTooBig, nameof(namedParams));
                    }
                }
                else
                {
                    if (namedParams.Length != 0)
                    {
                        // "Named parameter array can not be bigger than argument array."
                        throw new ArgumentException(SR.Arg_NamedParamTooBig, nameof(namedParams));
                    }
                }
            }
            #endregion

            #region COM Interop
            if (target != null && target.GetType().IsCOMObject)
            {
                throw new PlatformNotSupportedException(SR.Arg_PlatformNotSupportedInvokeMemberCom);
            }
            #endregion

            #region Check that any named paramters are not null
            if (namedParams != null && Array.IndexOf(namedParams, null) != -1)
            {
                // "Named parameter value must not be null."
                throw new ArgumentException(SR.Arg_NamedParamNull, nameof(namedParams));
            }
            #endregion

            int argCnt = (providedArgs != null) ? providedArgs.Length : 0;

            #region Get a Binder
            if (binder == null)
            {
                binder = DefaultBinder;
            }

            bool bDefaultBinder = (binder == DefaultBinder);
            #endregion

            #region Delegate to Activator.CreateInstance
            if ((bindingFlags & BindingFlags.CreateInstance) != 0)
            {
                if ((bindingFlags & BindingFlags.CreateInstance) != 0 && (bindingFlags & BinderNonCreateInstance) != 0)
                {
                    // "Can not specify both CreateInstance and another access type."
                    throw new ArgumentException(SR.Arg_CreatInstAccess, nameof(bindingFlags));
                }

                return(Activator.CreateInstance(this, bindingFlags, binder, providedArgs, culture));
            }
            #endregion

            // PutDispProperty and\or PutRefDispProperty ==> SetProperty.
            if ((bindingFlags & (BindingFlags.PutDispProperty | BindingFlags.PutRefDispProperty)) != 0)
            {
                bindingFlags |= BindingFlags.SetProperty;
            }

            #region Name
            if (name == null)
            {
                throw new ArgumentNullException(nameof(name));
            }

            if (name.Length == 0 || name.Equals(@"[DISPID=0]"))
            {
                name = GetDefaultMemberName();

                if (name == null)
                {
                    // in InvokeMember we always pretend there is a default member if none is provided and we make it ToString
                    name = "ToString";
                }
            }
            #endregion

            #region GetField or SetField
            bool IsGetField = (bindingFlags & BindingFlags.GetField) != 0;
            bool IsSetField = (bindingFlags & BindingFlags.SetField) != 0;

            if (IsGetField || IsSetField)
            {
                #region Preconditions
                if (IsGetField)
                {
                    if (IsSetField)
                    {
                        // "Can not specify both Get and Set on a field."
                        throw new ArgumentException(SR.Arg_FldSetGet, nameof(bindingFlags));
                    }

                    if ((bindingFlags & BindingFlags.SetProperty) != 0)
                    {
                        // "Can not specify both GetField and SetProperty."
                        throw new ArgumentException(SR.Arg_FldGetPropSet, nameof(bindingFlags));
                    }
                }
                else
                {
                    Debug.Assert(IsSetField);

                    if (providedArgs == null)
                    {
                        throw new ArgumentNullException(nameof(providedArgs));
                    }

                    if ((bindingFlags & BindingFlags.GetProperty) != 0)
                    {
                        // "Can not specify both SetField and GetProperty."
                        throw new ArgumentException(SR.Arg_FldSetPropGet, nameof(bindingFlags));
                    }

                    if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
                    {
                        // "Can not specify Set on a Field and Invoke on a method."
                        throw new ArgumentException(SR.Arg_FldSetInvoke, nameof(bindingFlags));
                    }
                }
                #endregion

                #region Lookup Field
                FieldInfo   selFld = null;
                FieldInfo[] flds   = GetMember(name, MemberTypes.Field, bindingFlags) as FieldInfo[];

                Debug.Assert(flds != null);

                if (flds.Length == 1)
                {
                    selFld = flds[0];
                }
                else if (flds.Length > 0)
                {
                    selFld = binder.BindToField(bindingFlags, flds, IsGetField ? Empty.Value : providedArgs[0], culture);
                }
                #endregion

                if (selFld != null)
                {
                    #region Invocation on a field
                    if (selFld.FieldType.IsArray || Object.ReferenceEquals(selFld.FieldType, typeof(System.Array)))
                    {
                        #region Invocation of an array Field
                        int idxCnt;

                        if ((bindingFlags & BindingFlags.GetField) != 0)
                        {
                            idxCnt = argCnt;
                        }
                        else
                        {
                            idxCnt = argCnt - 1;
                        }

                        if (idxCnt > 0)
                        {
                            // Verify that all of the index values are ints
                            int[] idx = new int[idxCnt];
                            for (int i = 0; i < idxCnt; i++)
                            {
                                try
                                {
                                    idx[i] = ((IConvertible)providedArgs[i]).ToInt32(null);
                                }
                                catch (InvalidCastException)
                                {
                                    throw new ArgumentException(SR.Arg_IndexMustBeInt);
                                }
                            }

                            // Set or get the value...
                            Array a = (Array)selFld.GetValue(target);

                            // Set or get the value in the array
                            if ((bindingFlags & BindingFlags.GetField) != 0)
                            {
                                return(a.GetValue(idx));
                            }
                            else
                            {
                                a.SetValue(providedArgs[idxCnt], idx);
                                return(null);
                            }
                        }
                        #endregion
                    }

                    if (IsGetField)
                    {
                        #region Get the field value
                        if (argCnt != 0)
                        {
                            throw new ArgumentException(SR.Arg_FldGetArgErr, nameof(bindingFlags));
                        }

                        return(selFld.GetValue(target));

                        #endregion
                    }
                    else
                    {
                        #region Set the field Value
                        if (argCnt != 1)
                        {
                            throw new ArgumentException(SR.Arg_FldSetArgErr, nameof(bindingFlags));
                        }

                        selFld.SetValue(target, providedArgs[0], bindingFlags, binder, culture);

                        return(null);

                        #endregion
                    }
                    #endregion
                }

                if ((bindingFlags & BinderNonFieldGetSet) == 0)
                {
                    throw new MissingFieldException(FullName, name);
                }
            }
            #endregion

            #region Property PreConditions
            // @Legacy - This is RTM behavior
            bool isGetProperty = (bindingFlags & BindingFlags.GetProperty) != 0;
            bool isSetProperty = (bindingFlags & BindingFlags.SetProperty) != 0;

            if (isGetProperty || isSetProperty)
            {
                #region Preconditions
                if (isGetProperty)
                {
                    Debug.Assert(!IsSetField);

                    if (isSetProperty)
                    {
                        throw new ArgumentException(SR.Arg_PropSetGet, nameof(bindingFlags));
                    }
                }
                else
                {
                    Debug.Assert(isSetProperty);

                    Debug.Assert(!IsGetField);

                    if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
                    {
                        throw new ArgumentException(SR.Arg_PropSetInvoke, nameof(bindingFlags));
                    }
                }
                #endregion
            }
            #endregion

            MethodInfo[] finalists = null;
            MethodInfo   finalist  = null;

            #region BindingFlags.InvokeMethod
            if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
            {
                #region Lookup Methods
                MethodInfo[] semiFinalists = GetMember(name, MemberTypes.Method, bindingFlags) as MethodInfo[];
                LowLevelListWithIList <MethodInfo> results = null;

                for (int i = 0; i < semiFinalists.Length; i++)
                {
                    MethodInfo semiFinalist = semiFinalists[i];
                    Debug.Assert(semiFinalist != null);

                    if (!semiFinalist.QualifiesBasedOnParameterCount(bindingFlags, CallingConventions.Any, new Type[argCnt]))
                    {
                        continue;
                    }

                    if (finalist == null)
                    {
                        finalist = semiFinalist;
                    }
                    else
                    {
                        if (results == null)
                        {
                            results = new LowLevelListWithIList <MethodInfo>(semiFinalists.Length);
                            results.Add(finalist);
                        }

                        results.Add(semiFinalist);
                    }
                }

                if (results != null)
                {
                    Debug.Assert(results.Count > 1);
                    finalists = new MethodInfo[results.Count];
                    results.CopyTo(finalists, 0);
                }
                #endregion
            }
            #endregion

            Debug.Assert(finalists == null || finalist != null);

            #region BindingFlags.GetProperty or BindingFlags.SetProperty
            if (finalist == null && isGetProperty || isSetProperty)
            {
                #region Lookup Property
                PropertyInfo[] semiFinalists = GetMember(name, MemberTypes.Property, bindingFlags) as PropertyInfo[];
                LowLevelListWithIList <MethodInfo> results = null;

                for (int i = 0; i < semiFinalists.Length; i++)
                {
                    MethodInfo semiFinalist = null;

                    if (isSetProperty)
                    {
                        semiFinalist = semiFinalists[i].GetSetMethod(true);
                    }
                    else
                    {
                        semiFinalist = semiFinalists[i].GetGetMethod(true);
                    }

                    if (semiFinalist == null)
                    {
                        continue;
                    }

                    BindingFlags expectedBindingFlags = semiFinalist.IsPublic ? BindingFlags.Public : BindingFlags.NonPublic;
                    if ((bindingFlags & expectedBindingFlags) != expectedBindingFlags)
                    {
                        continue;
                    }

                    if (!semiFinalist.QualifiesBasedOnParameterCount(bindingFlags, CallingConventions.Any, new Type[argCnt]))
                    {
                        continue;
                    }

                    if (finalist == null)
                    {
                        finalist = semiFinalist;
                    }
                    else
                    {
                        if (results == null)
                        {
                            results = new LowLevelListWithIList <MethodInfo>(semiFinalists.Length);
                            results.Add(finalist);
                        }

                        results.Add(semiFinalist);
                    }
                }

                if (results != null)
                {
                    Debug.Assert(results.Count > 1);
                    finalists = new MethodInfo[results.Count];
                    results.CopyTo(finalists, 0);
                }
                #endregion
            }
            #endregion

            if (finalist != null)
            {
                #region Invoke
                if (finalists == null &&
                    argCnt == 0 &&
                    finalist.GetParametersNoCopy().Length == 0 &&
                    (bindingFlags & BindingFlags.OptionalParamBinding) == 0)
                {
                    //if (useCache && argCnt == props[0].GetParameters().Length)
                    //    AddMethodToCache(name, bindingFlags, argCnt, providedArgs, props[0]);

                    return(finalist.Invoke(target, bindingFlags, binder, providedArgs, culture));
                }

                if (finalists == null)
                {
                    finalists = new MethodInfo[] { finalist }
                }
                ;

                if (providedArgs == null)
                {
                    providedArgs = Array.Empty <object>();
                }

                Object state = null;


                MethodBase invokeMethod = null;

                try { invokeMethod = binder.BindToMethod(bindingFlags, finalists, ref providedArgs, modifiers, culture, namedParams, out state); }
                catch (MissingMethodException) { }

                if (invokeMethod == null)
                {
                    throw new MissingMethodException(FullName, name);
                }

                //if (useCache && argCnt == invokeMethod.GetParameters().Length)
                //    AddMethodToCache(name, bindingFlags, argCnt, providedArgs, invokeMethod);

                Object result = ((MethodInfo)invokeMethod).Invoke(target, bindingFlags, binder, providedArgs, culture);

                if (state != null)
                {
                    binder.ReorderArgumentArray(ref providedArgs, state);
                }

                return(result);

                #endregion
            }

            throw new MissingMethodException(FullName, name);
        }
    }
Ejemplo n.º 13
0
        //
        // If throwIfMissingMetadata is false, returns null rather than throwing a MissingMetadataException.
        //
        internal sealed override IList <CustomAttributeTypedArgument> GetConstructorArguments(bool throwIfMissingMetadata)
        {
            int index = 0;
            LowLevelList <Handle> lazyCtorTypeHandles = null;
            LowLevelListWithIList <CustomAttributeTypedArgument> customAttributeTypedArguments = new LowLevelListWithIList <CustomAttributeTypedArgument>();

            foreach (FixedArgumentHandle fixedArgumentHandle in _customAttribute.FixedArguments)
            {
                CustomAttributeTypedArgument customAttributeTypedArgument =
                    ParseFixedArgument(
                        _reader,
                        fixedArgumentHandle,
                        throwIfMissingMetadata,
                        delegate()
                {
                    // If we got here, the custom attribute blob lacked type information (this is actually the typical case.) We must fallback to
                    // parsing the constructor's signature to get the type info.
                    if (lazyCtorTypeHandles == null)
                    {
                        IEnumerable <ParameterTypeSignatureHandle> parameterTypeSignatureHandles;
                        HandleType handleType = _customAttribute.Constructor.HandleType;
                        switch (handleType)
                        {
                        case HandleType.QualifiedMethod:
                            parameterTypeSignatureHandles = _customAttribute.Constructor.ToQualifiedMethodHandle(_reader).GetQualifiedMethod(_reader).Method.GetMethod(_reader).Signature.GetMethodSignature(_reader).Parameters;
                            break;

                        case HandleType.MemberReference:
                            parameterTypeSignatureHandles = _customAttribute.Constructor.ToMemberReferenceHandle(_reader).GetMemberReference(_reader).Signature.ToMethodSignatureHandle(_reader).GetMethodSignature(_reader).Parameters;
                            break;

                        default:
                            throw new BadImageFormatException();
                        }
                        LowLevelList <Handle> ctorTypeHandles = new LowLevelList <Handle>();
                        foreach (ParameterTypeSignatureHandle parameterTypeSignatureHandle in parameterTypeSignatureHandles)
                        {
                            ctorTypeHandles.Add(parameterTypeSignatureHandle.GetParameterTypeSignature(_reader).Type);
                        }
                        lazyCtorTypeHandles = ctorTypeHandles;
                    }
                    Handle typeHandle        = lazyCtorTypeHandles[index];
                    Exception exception      = null;
                    RuntimeType argumentType = _reflectionDomain.TryResolve(_reader, typeHandle, new TypeContext(null, null), ref exception);
                    if (argumentType == null)
                    {
                        if (throwIfMissingMetadata)
                        {
                            throw exception;
                        }
                        return(null);
                    }
                    return(argumentType);
                }
                        );

                if (customAttributeTypedArgument.ArgumentType == null)
                {
                    Debug.Assert(!throwIfMissingMetadata);
                    return(null);
                }

                customAttributeTypedArguments.Add(customAttributeTypedArgument);
                index++;
            }

            return(customAttributeTypedArguments);
        }
Ejemplo n.º 14
0
        //
        // If throwIfMissingMetadata is false, returns null rather than throwing a missing metadata exception.
        //
        internal sealed override IList <CustomAttributeTypedArgument> GetConstructorArguments(bool throwIfMissingMetadata)
        {
            int index = 0;

            HandleCollection parameterTypeSignatureHandles;
            HandleType       handleType = _customAttribute.Constructor.HandleType;

            switch (handleType)
            {
            case HandleType.QualifiedMethod:
                parameterTypeSignatureHandles = _customAttribute.Constructor.ToQualifiedMethodHandle(_reader).GetQualifiedMethod(_reader).Method.GetMethod(_reader).Signature.GetMethodSignature(_reader).Parameters;
                break;

            case HandleType.MemberReference:
                parameterTypeSignatureHandles = _customAttribute.Constructor.ToMemberReferenceHandle(_reader).GetMemberReference(_reader).Signature.ToMethodSignatureHandle(_reader).GetMethodSignature(_reader).Parameters;
                break;

            default:
                throw new BadImageFormatException();
            }
            Handle[] ctorTypeHandles = parameterTypeSignatureHandles.ToArray();

            LowLevelListWithIList <CustomAttributeTypedArgument> customAttributeTypedArguments = new LowLevelListWithIList <CustomAttributeTypedArgument>();

            foreach (Handle fixedArgumentHandle in _customAttribute.FixedArguments)
            {
                Handle          typeHandle   = ctorTypeHandles[index];
                Exception?      exception    = null;
                RuntimeTypeInfo?argumentType = typeHandle.TryResolve(_reader, new TypeContext(null, null), ref exception);
                if (argumentType == null)
                {
                    if (throwIfMissingMetadata)
                    {
                        throw exception !;
                    }
                    return(null);
                }

                Exception e = fixedArgumentHandle.TryParseConstantValue(_reader, out object?value);
                CustomAttributeTypedArgument customAttributeTypedArgument;
                if (e != null)
                {
                    if (throwIfMissingMetadata)
                    {
                        throw e;
                    }
                    else
                    {
                        return(null);
                    }
                }
                else
                {
                    customAttributeTypedArgument = WrapInCustomAttributeTypedArgument(value, argumentType);
                }

                customAttributeTypedArguments.Add(customAttributeTypedArgument);
                index++;
            }

            return(customAttributeTypedArguments);
        }