Example #1
0
 internal abstract int GetTargetAttributeSignatureIndex(Symbol targetSymbol, AttributeDescription description);
        private void ConfirmModuleAttributePresentAndAddingToAssemblyResultsInSignedOutput(MemoryStream moduleContents, AttributeDescription expectedModuleAttr)
        {
            //a module doesn't get signed for real. It should have either a keyfile or keycontainer attribute
            //parked on a typeRef named 'AssemblyAttributesGoHere.' When the module is added to an assembly, the
            //resulting assembly is signed with the key referred to by the aforementioned attribute.

            EmitResult success;
            var tempFile = Temp.CreateFile();
            moduleContents.Position = 0;

            using (var metadata = ModuleMetadata.CreateFromStream(moduleContents))
            {
                var flags = metadata.Module.PEReaderOpt.PEHeaders.CorHeader.Flags;
                //confirm file does not claim to be signed
                Assert.Equal(0, (int)(flags & CorFlags.StrongNameSigned));
                Handle token = metadata.Module.GetTypeRef(metadata.Module.GetAssemblyRef("mscorlib"), "System.Runtime.CompilerServices", "AssemblyAttributesGoHere");
                Assert.False(token.IsNil);   //could the type ref be located? If not then the attribute's not there.
                var attrInfos = metadata.Module.FindTargetAttributes(token, expectedModuleAttr);
                Assert.Equal(1, attrInfos.Count());

                var source = @"
public class Z
{
}";

                //now that the module checks out, ensure that adding it to a compilation outputing a dll
                //results in a signed assembly.
                var assemblyComp = CreateCompilationWithMscorlib(source,
                    new[] { metadata.GetReference() },
                    TestOptions.ReleaseDll.WithStrongNameProvider(s_defaultProvider));

                using (var finalStrm = tempFile.Open())
                {
                    success = assemblyComp.Emit(finalStrm);
                }
            }

            success.Diagnostics.Verify();

            Assert.True(success.Success);
            AssertFileIsSigned(tempFile);
        }
Example #3
0
 internal bool IsTargetAttribute(Symbol targetSymbol, AttributeDescription description)
 {
     return GetTargetAttributeSignatureIndex(targetSymbol, description) != -1;
 }
Example #4
0
        internal static int IndexOfAttribute(this ImmutableArray<BaseAttributeData> attributes, Symbol targetSymbol, AttributeDescription description)
        {
            for (int i = 0; i < attributes.Length; i++)
            {
                if (attributes[i].IsTargetAttribute(targetSymbol, description))
                {
                    return i;
                }
            }

            return -1;
        }
Example #5
0
        /// <summary>
        /// This method finds an attribute by metadata name and signature. The algorithm for signature matching is similar to the one
        /// in Module.GetTargetAttributeSignatureIndex. Note, the signature matching is limited to primitive types
        /// and System.Type.  It will not match an arbitrary signature but it is sufficient to match the signatures of the current set of
        /// well known attributes.
        /// </summary>
        /// <param name="targetSymbol">The symbol which is the target of the attribute</param>
        /// <param name="description">The attribute to match.</param>
        internal override int GetTargetAttributeSignatureIndex(Symbol targetSymbol, AttributeDescription description)
        {
            if (!IsTargetAttribute(description.Namespace, description.Name))
            {
                return -1;
            }

            var ctor = this.AttributeConstructor;

            // Ensure that the attribute data really has a constructor before comparing the signature.
            if ((object)ctor == null)
            {
                return -1;
            }

            // Lazily loaded System.Type type symbol
            TypeSymbol lazySystemType = null;

            ImmutableArray<ParameterSymbol> parameters = ctor.Parameters;
            bool foundMatch = false;

            for (int i = 0; i < description.Signatures.Length; i++)
            {
                byte[] targetSignature = description.Signatures[i];
                if (targetSignature[0] != (byte)SignatureAttributes.Instance)
                {
                    continue;
                }

                byte parameterCount = targetSignature[1];
                if (parameterCount != parameters.Length)
                {
                    continue;
                }

                if ((SignatureTypeCode)targetSignature[2] != SignatureTypeCode.Void)
                {
                    continue;
                }

                foundMatch = (targetSignature.Length == 3);
                int k = 0;
                for (int j = 3; j < targetSignature.Length; j++)
                {
                    if (k >= parameters.Length)
                    {
                        break;
                    }

                    TypeSymbol parameterType = parameters[k].Type;
                    SpecialType specType = parameterType.SpecialType;
                    byte targetType = targetSignature[j];

                    if (targetType == (byte)SignatureTypeCode.TypeHandle)
                    {
                        j++;

                        if (parameterType.Kind != SymbolKind.NamedType && parameterType.Kind != SymbolKind.ErrorType)
                        {
                            foundMatch = false;
                            break;
                        }

                        var namedType = (NamedTypeSymbol)parameterType;
                        AttributeDescription.TypeHandleTargetInfo targetInfo = AttributeDescription.TypeHandleTargets[targetSignature[j]];

                        // Compare name and containing symbol name. Uses HasNameQualifier
                        // extension method to avoid string allocations.
                        if (!string.Equals(namedType.MetadataName, targetInfo.Name, System.StringComparison.Ordinal) ||
                            !namedType.HasNameQualifier(targetInfo.Namespace))
                        {
                            foundMatch = false;
                            break;
                        }

                        targetType = (byte)targetInfo.Underlying;

                        if (parameterType.IsEnumType())
                        {
                            throw new System.NotImplementedException();
                            //specType = parameterType.GetEnumUnderlyingType().SpecialType;
                        }
                    }
                    else if (parameterType.IsArray())
                    {
                        specType = ((ArrayTypeSymbol)parameterType).ElementType.SpecialType;
                    }

                    switch (targetType)
                    {
                        case (byte)SignatureTypeCode.Boolean:
                            foundMatch = specType == SpecialType.System_Boolean;
                            k += 1;
                            break;

                        case (byte)SignatureTypeCode.Char:
                            foundMatch = specType == SpecialType.System_Char;
                            k += 1;
                            break;

                        case (byte)SignatureTypeCode.SByte:
                            foundMatch = specType == SpecialType.System_SByte;
                            k += 1;
                            break;

                        case (byte)SignatureTypeCode.Byte:
                            foundMatch = specType == SpecialType.System_Byte;
                            k += 1;
                            break;

                        case (byte)SignatureTypeCode.Int16:
                            foundMatch = specType == SpecialType.System_Int16;
                            k += 1;
                            break;

                        case (byte)SignatureTypeCode.UInt16:
                            foundMatch = specType == SpecialType.System_UInt16;
                            k += 1;
                            break;

                        case (byte)SignatureTypeCode.Int32:
                            foundMatch = specType == SpecialType.System_Int32;
                            k += 1;
                            break;

                        case (byte)SignatureTypeCode.UInt32:
                            foundMatch = specType == SpecialType.System_UInt32;
                            k += 1;
                            break;

                        case (byte)SignatureTypeCode.Int64:
                            foundMatch = specType == SpecialType.System_Int64;
                            k += 1;
                            break;

                        case (byte)SignatureTypeCode.UInt64:
                            foundMatch = specType == SpecialType.System_UInt64;
                            k += 1;
                            break;

                        case (byte)SignatureTypeCode.Single:
                            foundMatch = specType == SpecialType.System_Single;
                            k += 1;
                            break;

                        case (byte)SignatureTypeCode.Double:
                            foundMatch = specType == SpecialType.System_Double;
                            k += 1;
                            break;

                        case (byte)SignatureTypeCode.String:
                            foundMatch = specType == SpecialType.System_String;
                            k += 1;
                            break;

                        case (byte)SignatureTypeCode.Object:
                            foundMatch = specType == SpecialType.System_Object;
                            k += 1;
                            break;

                        case (byte)SerializationTypeCode.Type:
                            if ((object)lazySystemType == null)
                            {
                                lazySystemType = GetSystemType(targetSymbol);
                            }

                            foundMatch = parameterType == lazySystemType;
                            k += 1;
                            break;

                        case (byte)SignatureTypeCode.SZArray:
                            // Skip over and check the next byte
                            foundMatch = parameterType.IsArray();
                            break;

                        default:
                            return -1;
                    }

                    if (!foundMatch)
                    {
                        break;
                    }
                }

                if (foundMatch)
                {
                    return i;
                }
            }

            Debug.Assert(!foundMatch);
            return -1;
        }
Example #6
0
        /// <summary>
        /// Returns a possibly ExtensionAttribute filtered roArray of attributes. If
        /// filterExtensionAttributes is set to true, the method will remove all ExtensionAttributes
        /// from the returned array. If it is false, the parameter foundExtension will always be set to
        /// false and can be safely ignored.
        /// 
        /// The paramArrayAttribute parameter is similar to the foundExtension parameter, but instead
        /// of just indicating if the attribute was found, the parameter is set to the attribute handle
        /// for the ParamArrayAttribute if any is found and is null otherwise. This allows NoPia to filter
        /// the attribute out for the symbol but still cache it separately for emit.
        /// </summary>
        internal ImmutableArray<AttributeData> GetCustomAttributesForToken(EntityHandle token,
            out CustomAttributeHandle filteredOutAttribute1,
            AttributeDescription filterOut1,
            out CustomAttributeHandle filteredOutAttribute2,
            AttributeDescription filterOut2)
        {
            filteredOutAttribute1 = default(CustomAttributeHandle);
            filteredOutAttribute2 = default(CustomAttributeHandle);
            ArrayBuilder<AttributeData> customAttributesBuilder = null;

            try
            {
                foreach (var customAttributeHandle in _module.GetCustomAttributesOrThrow(token))
                {
                    if (filterOut1.Signatures != null &&
                        Module.GetTargetAttributeSignatureIndex(customAttributeHandle, filterOut1) != -1)
                    {
                        // It is important to capture the last application of the attribute that we run into,
                        // it makes a difference for default and constant values.
                        filteredOutAttribute1 = customAttributeHandle;
                        continue;
                    }

                    if (filterOut2.Signatures != null &&
                        Module.GetTargetAttributeSignatureIndex(customAttributeHandle, filterOut2) != -1)
                    {
                        // It is important to capture the last application of the attribute that we run into,
                        // it makes a difference for default and constant values.
                        filteredOutAttribute2 = customAttributeHandle;
                        continue;
                    }

                    if (customAttributesBuilder == null)
                    {
                        customAttributesBuilder = ArrayBuilder<AttributeData>.GetInstance();
                    }

                    customAttributesBuilder.Add(new PEAttributeData(this, customAttributeHandle));
                }
            }
            catch (BadImageFormatException)
            { }

            if (customAttributesBuilder != null)
            {
                return customAttributesBuilder.ToImmutableAndFree();
            }

            return ImmutableArray<AttributeData>.Empty;
        }
Example #7
0
 /// <summary>
 /// Matches an attribute by metadata namespace, metadata type name and metadata signature. Does not load the
 /// type symbol for the attribute.
 /// </summary>
 /// <param name="targetSymbol">Target symbol.</param>
 /// <param name="description">Attribute to match.</param>
 /// <returns>
 /// An index of the target constructor signature in
 /// signatures array, -1 if
 /// this is not the target attribute.
 /// </returns>
 internal override int GetTargetAttributeSignatureIndex(Symbol targetSymbol, AttributeDescription description)
 {
     // Matching an attribute by name should not load the attribute class.
     return _decoder.GetTargetAttributeSignatureIndex(_handle, description);
 }