Пример #1
0
        internal void InitializeCommon()
        {
            ICliMetadataModuleTableRow[] modules = this.Modules.GetMetadata();

            var typeTables = (from moduleRow in modules
                              let ts = moduleRow.MetadataRoot.TableStream
                                       where ts.TypeDefinitionTable != null
                                       select ts.TypeDefinitionTable).ToArray();

            if (typeTables.Length == 0)
            {
                return;
            }
            HashSet <Tuple <int, uint> > namespaceIndices = new HashSet <Tuple <int, uint> >();

            Dictionary <uint, CliMetadataTypeDefinitionLockedTableRow[]> nonNestedTypes = new Dictionary <uint, CliMetadataTypeDefinitionLockedTableRow[]>();
            Dictionary <uint, int> nonNestedCounts = new Dictionary <uint, int>();

            /* *
             * Breakdown the types by their namespace index, and
             * create a unique list of namespaceIndices via a HashSet<T>.
             * *
             * Copy the table to a local set to avoid redundant load
             * checks, and to instruct it to read the full table sequentially.
             * */
            int totalTypeCount = 0;

            for (int typeTable = 0; typeTable < typeTables.Length; typeTable++)
            {
                totalTypeCount += typeTables[typeTable].Count;
            }
            ICliMetadataTypeDefinitionTableRow[] types = new ICliMetadataTypeDefinitionTableRow[totalTypeCount];
            for (int moduleIndex = 0, cOff = 0; moduleIndex < typeTables.Length; cOff += typeTables[moduleIndex++].Count)
            {
                typeTables[moduleIndex].CopyTo(types, cOff);
            }
            ICliMetadataTypeDefinitionTable moduleTypes = typeTables[0];

            for (int typeIndex = 0, moduleIndex = 0, moduleOffset = 0; typeIndex < types.Length; typeIndex++, moduleOffset++)
            {
moduleCheck:
                if (moduleOffset >= moduleTypes.Count)
                {
                    moduleIndex++;
                    if (moduleIndex < typeTables.Length)
                    {
                        moduleTypes = typeTables[moduleIndex];
                    }
                    moduleOffset = 0;
                    goto moduleCheck;
                }
                var typeRow = types[typeIndex];
                if ((typeRow.TypeAttributes & TypeAttributes.VisibilityMask) == TypeAttributes.NotPublic ||
                    (typeRow.TypeAttributes & TypeAttributes.VisibilityMask) == TypeAttributes.Public)
                {
                    uint nsIndex = typeRow.NamespaceIndex;
                    namespaceIndices.Add(Tuple.Create(moduleIndex, nsIndex));
                    CliMetadataTypeDefinitionLockedTableRow[] currentRows;
                    if (!nonNestedTypes.TryGetValue(nsIndex, out currentRows))
                    {
                        nonNestedTypes.Add(nsIndex, currentRows = new CliMetadataTypeDefinitionLockedTableRow[4]);
                        nonNestedCounts.Add(nsIndex, 0);
                    }
                    CliMetadataTypeDefinitionLockedTableRow[] spaceAvailableRows = currentRows.EnsureSpaceExists(nonNestedCounts[nsIndex], 1);
                    if (spaceAvailableRows != currentRows)
                    {
                        nonNestedTypes[nsIndex] = currentRows = spaceAvailableRows;
                    }
                    currentRows[nonNestedCounts[nsIndex]++] = typeRow as CliMetadataTypeDefinitionLockedTableRow;
                }
            }

            var namespaceIndicesArray = namespaceIndices.ToArray();

            CliMetadataTypeDefinitionLockedTableRow[] topLevelRows;
            if (nonNestedTypes.TryGetValue(0, out topLevelRows))
            {
                int topLevelCount = nonNestedCounts[0];
                int noModuleCount = 0;
                for (int typeIndex = 0; typeIndex < topLevelCount; typeIndex++)
                {
                    if (topLevelRows[typeIndex].Index != CliMetadataTypeDefinitionTableReader.__COR_TYPEDEFINITION_MODULE_INDEX__)
                    {
                        noModuleCount++;
                    }
                }

                if (topLevelRows.Length != noModuleCount)
                {
                    CliMetadataTypeDefinitionLockedTableRow[] topLevelRowsActual = new CliMetadataTypeDefinitionLockedTableRow[noModuleCount];

                    /* *
                     * Filter the entries based off of their index.  The special <Module> type
                     * is the global fields and methods.  There's no need to include them and
                     * have to inject checks elsewhere to filter it out.
                     * */
                    for (int typeIndex = 0, cOffset = 0; typeIndex < topLevelCount; typeIndex++)
                    {
                        if (topLevelRows[typeIndex].Index != CliMetadataTypeDefinitionTableReader.__COR_TYPEDEFINITION_MODULE_INDEX__)
                        {
                            topLevelRowsActual[cOffset++] = topLevelRows[typeIndex];
                        }
                    }

                    Array.Sort(topLevelRowsActual, _CompareTo_);
                    topLevelRows = topLevelRowsActual;
                }
                else
                {
                    Array.Sort(topLevelRows, _CompareTo_);
                }
            }
            else
            {
                topLevelRows = new CliMetadataTypeDefinitionLockedTableRow[0];
            }

            CliNamespaceKeyedTree     partialOrFullNamespaces = new CliNamespaceKeyedTree(topLevelRows);
            Dictionary <string, uint> partIndex = new Dictionary <string, uint>();

            for (int namespaceIndex = 0; namespaceIndex < namespaceIndicesArray.Length; namespaceIndex++)
            {
                uint currentIndex = namespaceIndicesArray[namespaceIndex].Item2;
                if (currentIndex == 0)
                {
                    continue;
                }
                var    currentRows   = nonNestedTypes[currentIndex];
                var    currentCount  = nonNestedCounts[currentIndex];
                var    module        = modules[namespaceIndicesArray[namespaceIndex].Item1];
                string currentString = module.MetadataRoot.StringsHeap[currentIndex];

                /* *
                 * Eliminate the null row entries by reducing the sizes
                 * of the arrays.
                 * */
                if (currentRows.Length != currentCount)
                {
                    var currentRowsCopy = new CliMetadataTypeDefinitionLockedTableRow[currentCount];
                    Array.ConstrainedCopy(currentRows, 0, currentRowsCopy, 0, currentCount);
                    Array.Sort(currentRowsCopy, _CompareTo_);
                    currentRows = currentRowsCopy;
                }
                else
                {
                    Array.Sort(currentRows, _CompareTo_);
                }

                CliNamespaceKeyedTree current = partialOrFullNamespaces;
                string[] breakdown            = currentString.Split(new[] { "." }, StringSplitOptions.None);
                int      currentLength        = 0;
                bool     first = true;
                foreach (var part in breakdown)
                {
                    /* *
                     * Position tracking, there is no period preceeding
                     * the first namespace identifier.
                     * */
                    if (first)
                    {
                        first = false;
                    }
                    else
                    {
                        currentLength++;
                    }
                    uint partId;

                    /* *
                     * Don't use the namespace index as a key for the
                     * partial or full dictionary.
                     * *
                     * Use the substring of the current namespace as a guide,
                     * since the 'System' of 'System'.Collections.Generic would
                     * be a different string heap index than 'System' alone,
                     * create our own reference lookup for the individual
                     * segments of the namespace's name.
                     * *
                     * Use the segment's hash code to determine the part index;
                     * while there's a chance for collision, the chances are slim.
                     * Main reason is: while the space of possible character combinations
                     * is small, the chance of a user-written name overlapping, in the
                     * realm of its sibling namespaces, is unlikely.
                     * */
                    if (!partIndex.TryGetValue(part, out partId))
                    {
                        partIndex.Add(part, partId = (uint)part.GetHashCode());
                    }
                    int startIndex = currentLength;
                    currentLength += part.Length;
                    bool fullName = currentLength == currentString.Length;
                    CliNamespaceKeyedTreeNode next;
                    if (!current.TryGetValue(partId, out next))
                    {
                        if (fullName)
                        {
                            current = current.Add(partId, currentIndex, startIndex, currentLength - startIndex, currentRows, module.MetadataRoot.StringsHeap);
                        }
                        else
                        {
                            current = current.Add(partId, currentIndex, startIndex, currentLength - startIndex, module.MetadataRoot.StringsHeap);
                        }
                    }
                    else
                    {
                        current = next;
                        if (fullName)
                        {
                            current.PushModuleTypes(currentRows);
                        }
                    }
                }
            }
            this.namespaceInformation = partialOrFullNamespaces;
        }
Пример #2
0
        private static bool CheckForSecuritySuppressionAttribute(ICliMetadataRoot metadataRoot, ICliMetadataTypeDefinitionTable typeDefTable, ICliMetadataTypeDefinitionTableRow typeDefinition)
        {
            bool hasSuppressionAttribute = false;

            foreach (var customAttr in typeDefinition.CustomAttributes)
            {
                switch (customAttr.CtorSource)
                {
                case CliMetadataCustomAttributeTypeTag.MethodDefinition:
                {
                    var methodDef = (ICliMetadataMethodDefinitionTableRow)customAttr.Ctor;
                    for (int i = 1; i <= metadataRoot.TableStream.TypeDefinitionTable.Count; i++)
                    {
                        var current = typeDefTable[i];
                        if (current.MethodStartIndex <= methodDef.Index)
                        {
                            if (i == metadataRoot.TableStream.TypeDefinitionTable.Count)
                            {
                                if (current.Name == "SuppressUnmanagedCodeSecurityAttribute" &&
                                    current.Namespace == "System.Security")
                                {
                                    hasSuppressionAttribute = true;
                                    goto breakLoop;
                                }
                            }
                            else
                            {
                                var next = typeDefTable[i + 1];
                                if (next.MethodStartIndex <= methodDef.Index)
                                {
                                    continue;
                                }
                                if (current.Name == "SuppressUnmanagedCodeSecurityAttribute" &&
                                    current.Namespace == "System.Security")
                                {
                                    hasSuppressionAttribute = true;
                                    goto breakLoop;
                                }
                            }
                        }
                    }
                }
                break;

                case CliMetadataCustomAttributeTypeTag.MemberReference:
                    var methodRef = (ICliMetadataMemberReferenceTableRow)customAttr.Ctor;
                    if (methodRef.ClassSource == CliMetadataMemberRefParentTag.TypeReference)
                    {
                        var typeRef = (ICliMetadataTypeRefTableRow)methodRef.Class;
                        if (typeRef.Name == "SuppressUnmanagedCodeSecurityAttribute" &&
                            typeRef.Namespace == "System.Security")
                        {
                            hasSuppressionAttribute = true;
                            goto breakLoop;
                        }
                    }
                    else if (methodRef.ClassSource == CliMetadataMemberRefParentTag.TypeDefinition)
                    {
                        var typeDef = (ICliMetadataTypeDefinitionTableRow)methodRef.Class;
                        if (typeDef.Name == "SuppressUnmanagedCodeSecurityAttribute" &&
                            typeDef.Namespace == "System.Security")
                        {
                            hasSuppressionAttribute = true;
                            goto breakLoop;
                        }
                    }
                    break;
                }
            }
breakLoop:
            return(hasSuppressionAttribute);
        }