Skip to content

Commit

Permalink
Merge pull request dotnet#11772 from cston/217689-s
Browse files Browse the repository at this point in the history
Throw BadImageFormatException decoding TypeRef with resolution scope with nil AssemblyRef
  • Loading branch information
cston committed Jun 6, 2016
2 parents deabd1d + b0bdf16 commit 978dabc
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 6 deletions.
8 changes: 6 additions & 2 deletions src/Compilers/Core/Portable/MetadataReader/MetadataDecoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -504,9 +504,13 @@ private TypeSymbol GetTypeByNameOrThrow(

if (tokenType == HandleKind.AssemblyReference)
{
// TODO: Can refer to the containing assembly?
isNoPiaLocalType = false;
return LookupTopLevelTypeDefSymbol(Module.GetAssemblyReferenceIndexOrThrow((AssemblyReferenceHandle)tokenResolutionScope), ref fullName);
var assemblyRef = (AssemblyReferenceHandle)tokenResolutionScope;
if (assemblyRef.IsNil)
{
throw new BadImageFormatException();
}
return LookupTopLevelTypeDefSymbol(Module.GetAssemblyReferenceIndexOrThrow(assemblyRef), ref fullName);
}

if (tokenType == HandleKind.ModuleReference)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

Imports System.Runtime.CompilerServices
Imports CompilationCreationTestHelpers
Imports System.Collections.Immutable
Imports Microsoft.CodeAnalysis.Test.Utilities
Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.CodeAnalysis.VisualBasic
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Imports Roslyn.Test.Utilities


Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests.Symbols.Metadata.PE

Public Class HasUnsupportedMetadata : Inherits BasicTestBase
Expand Down Expand Up @@ -435,6 +432,86 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests.Symbols.Metadata.PE
Assert.True(tok.HasUnsupportedMetadata)
End Sub

''' <summary>
''' Throw a (handled) BadImageFormatException from MetadataDecoder
''' for a TypeRef assembly resolution scope with Nil AssemblyRef.
''' </summary>
<Fact>
<WorkItem(217689, "https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems?_a=edit&id=217689")>
Public Sub ResolutionScopeNilAssembly()
Dim options = TestOptions.ReleaseDll.WithDeterministic(True)
Dim comp1 = CreateCompilationWithMscorlib(
{"Public Class A
End Class"},
options:=options,
assemblyName:="4D94B345-92CE-46BB-891E-048109648A0A")
comp1.VerifyDiagnostics()
Dim bytes1 = comp1.EmitToArray()
Dim ref1 = AssemblyMetadata.CreateFromImage(bytes1).GetReference()

Dim comp2 = CreateCompilationWithMscorlib(
{"Public Class B
Inherits A
End Class"},
options:=options,
assemblyName:="D4954046-BDDC-42C4-98F8-7E5573C16C33",
references:=New MetadataReference() {ref1})
comp2.VerifyDiagnostics()
Dim bytes2 = comp2.EmitToArray()
' Construct an unexpected assembly resolution scope from the valid compilation.
' Metadata contains a single TypeRef with assembly resolution scope where the
' scope is AssemblyRef 2: specifically the TypeRef to base class A. Replace that
' assembly resolution scope with AssemblyRef 0 (the unexpected value). In the
' TypeRef signatures below, 10 and 2 are the assembly scopes (AssemblyRef << 2 | 2).
' (To verify, break in MetadataWriter.SerializeTypeRefTable when emitting comp2.)
bytes2 = ReplaceBytes(bytes2, {10, 0, 82, 0, 0, 0}, {2, 0, 82, 0, 0, 0})
Dim ref2 = AssemblyMetadata.CreateFromImage(bytes2).GetReference()

Dim comp3 = CreateCompilationWithMscorlib(
{"Class C
Shared Sub Main()
Dim o As New B()
End Sub
End Class"},
options:=options,
references:=New MetadataReference() {ref2})
comp3.VerifyDiagnostics()

Dim tree = comp3.SyntaxTrees(0)
Dim model = comp3.GetSemanticModel(tree)
Dim decl = tree.GetRoot().DescendantNodes.OfType(Of ObjectCreationExpressionSyntax).Single()
Dim type = DirectCast(model.GetTypeInfo(decl).Type, TypeSymbol)
Assert.Equal("B", type.ToTestDisplayString())
Assert.False(type.IsErrorType())
Assert.True(type.BaseType.IsErrorType()) ' Handled exception decoding base type TypeRef.
End Sub

Private Shared Function ReplaceBytes(bytes As ImmutableArray(Of Byte), before As Byte(), after As Byte()) As ImmutableArray(Of Byte)
Dim index = IndexOfBytes(bytes, before, 0)
Debug.Assert(index >= 0)
Debug.Assert(IndexOfBytes(bytes, before, index + 1) < 0)
Dim builder = ArrayBuilder(Of Byte).GetInstance()
builder.AddRange(bytes.Take(index))
builder.AddRange(after)
builder.AddRange(bytes.Skip(index + before.Length))
Return builder.ToImmutableAndFree()
End Function

Private Shared Function IndexOfBytes(bytes As ImmutableArray(Of Byte), pattern As Byte(), startIndex As Integer) As Integer
Dim n = bytes.Length
Dim m = pattern.Length
For i = startIndex To n - m - 1
For j = 0 To m - 1
If bytes(i + j) <> pattern(j) Then
GoTo EndOfLoop
End If
Next
Return i
EndOfLoop:
Next
Return -1
End Function

End Class

End Namespace
Expand Down

0 comments on commit 978dabc

Please sign in to comment.