/// <inheritdoc /> public bool Equals(InvalidTypeDefOrRef x, InvalidTypeDefOrRef y) { if (ReferenceEquals(x, y)) { return(true); } if (ReferenceEquals(x, null) || ReferenceEquals(y, null)) { return(false); } return(x.Error == y.Error); }
/// <summary> /// Determines whether two types are considered equal according to their signature. /// </summary> /// <param name="type1">The first type to compare.</param> /// <param name="type2">The second type to compare.</param> /// <returns><c>True</c> if the types are considered equal, <c>False</c> otherwise.</returns> public bool Equals(InvalidTypeDefOrRef type1, InvalidTypeDefOrRef type2) { if (type1 == null && type2 == null) { return(true); } if (type1 == null || type2 == null) { return(false); } return(type1.Error == type2.Error); }
/// <inheritdoc /> public bool Equals(ITypeDescriptor x, ITypeDescriptor y) { if (ReferenceEquals(x, y)) { return(true); } if (x is null || y is null) { return(false); } return(x switch { InvalidTypeDefOrRef invalidType => Equals(invalidType, y as InvalidTypeDefOrRef), TypeSpecification specification => Equals(specification, y as TypeSpecification), TypeSignature signature => Equals(signature, y as TypeSignature), _ => SimpleTypeEquals(x, y) });
/// <summary> /// Reads a single coded index to a type definition or reference and resolves it. /// </summary> /// <param name="image">The image the type resides in.</param> /// <param name="reader">The reader to use.</param> /// <param name="protection">The recursion protection that is used to detect malicious loops in the metadata.</param> /// <returns>The type, or <c>null</c> if recursion was detected.</returns> protected static ITypeDefOrRef ReadTypeDefOrRef(MetadataImage image, IBinaryStreamReader reader, RecursionProtection protection) { var tableStream = image.Header.GetStream <TableStream>(); if (!reader.TryReadCompressedUInt32(out uint codedIndex)) { return(null); } // If the resolved type is a TypeSpec, it can be a (malicious) loop to the same blob signature that we // were coming from. var token = tableStream.GetIndexEncoder(CodedIndex.TypeDefOrRef).DecodeIndex(codedIndex); if (token.TokenType == MetadataTokenType.TypeSpec && !protection.TraversedTokens.Add(token)) { return(InvalidTypeDefOrRef.Get(InvalidTypeSignatureError.MetadataLoop)); } image.TryResolveMember(token, out var type); return(type as ITypeDefOrRef); }
public void MaliciousMetadataLoop() { var spec = CreateDummyType(); var image = spec.Image; var importer = new ReferenceImporter(image); spec.Signature = new MaliciousTypeSignature( importer.ImportType(typeof(object)), spec); var header = image.Header; var mapping = header.UnlockMetadata(); var newImage = header.LockMetadata(); var newSpec = (TypeSpecification)newImage.ResolveMember(mapping[spec]); Assert.Equal( InvalidTypeDefOrRef.Get(InvalidTypeSignatureError.MetadataLoop), newSpec.Signature.GetElementType(), Comparer); }
/// <summary> /// Reads a TypeDefOrRef coded index from the provided blob reader. /// </summary> /// <param name="module">The module containing the blob signature.</param> /// <param name="reader">The blob reader.</param> /// <param name="protection">The object responsible for detecting infinite recursion.</param> /// <param name="allowTypeSpec">Indicates the coded index to the type is allowed to be decoded to a member in /// the type specification table.</param> /// <returns>The decoded and resolved type definition or reference.</returns> protected static ITypeDefOrRef ReadTypeDefOrRef(ModuleDefinition module, IBinaryStreamReader reader, RecursionProtection protection, bool allowTypeSpec) { if (!reader.TryReadCompressedUInt32(out uint codedIndex)) { return(InvalidTypeDefOrRef.Get(InvalidTypeSignatureError.BlobTooShort)); } var decoder = module.GetIndexEncoder(CodedIndex.TypeDefOrRef); var token = decoder.DecodeIndex(codedIndex); // Check if type specs can be encoded. if (token.Table == TableIndex.TypeSpec && !allowTypeSpec) { return(InvalidTypeDefOrRef.Get(InvalidTypeSignatureError.IllegalTypeSpec)); } switch (token.Table) { // Check for infinite recursion. case TableIndex.TypeSpec when !protection.TraversedTokens.Add(token): return(InvalidTypeDefOrRef.Get(InvalidTypeSignatureError.MetadataLoop)); // Any other type is legal. case TableIndex.TypeSpec: case TableIndex.TypeDef: case TableIndex.TypeRef: if (module.TryLookupMember(token, out var member) && member is ITypeDefOrRef typeDefOrRef) { return(typeDefOrRef); } break; } return(InvalidTypeDefOrRef.Get(InvalidTypeSignatureError.InvalidCodedIndex)); }
/// <inheritdoc /> public int GetHashCode(InvalidTypeDefOrRef obj) { return((int)obj.Error); }