Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions src/coreclr/vm/assembly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2590,12 +2590,22 @@ ReleaseHolder<FriendAssemblyDescriptor> FriendAssemblyDescriptor::CreateFriendAs
// Create an AssemblyNameObject from the string.
FriendAssemblyNameHolder pFriendAssemblyName;
pFriendAssemblyName = new FriendAssemblyName_t;
hr = pFriendAssemblyName->InitNoThrow(displayName);
Comment thread
AaronRobinsonMSFT marked this conversation as resolved.

if (SUCCEEDED(hr))
EX_TRY
{
pFriendAssemblyName->Init(displayName);
}
EX_HOOK
{
hr = pFriendAssemblyName->CheckFriendAssemblyName();
// Preserve the underlying reason the friend assembly name could not be
// parsed (e.g. a malformed identity string) as the inner exception, while
// reporting the assembly that declared the invalid friend.
Exception *pInnerException = GET_EXCEPTION();
if (!pInnerException->IsTransient())
EEFileLoadException::Throw(pAssembly, pInnerException->GetHR(), pInnerException);
Comment thread
elinor-fung marked this conversation as resolved.
}
EX_END_HOOK

hr = pFriendAssemblyName->CheckFriendAssemblyName();

if (FAILED(hr))
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.IO;
using System.Runtime.CompilerServices;
using Xunit;

[assembly: InternalsVisibleTo(InvalidFriendAssemblyName.InvalidAssemblyName)]

public class InvalidFriendAssemblyName
{
internal const string InvalidAssemblyName = "Broken,PublicKey=00240000048000009400000006020000002400005253413100040000010001002d07581667cbf8caf9786ac8d5257eb2c77eb2643a1af1bb89d4286e27a3ff5d805408c9f1a0a392d2f478ca2b9c68e43cdcdcea2d7cf0618dd8ba48858bf5fc74c7fc2af7a29f936398c0f61a2165d08ac4fcc8e8ad04e24633b7ca31a7c13f750ae75e53cea55ced97d3289fd100dbe2661a802bf8bd2acb0b6893ef3fb79c,PublicKeyToken=282361b99ded7e8e";

// Only CoreCLR surfaces the invalid friend name as a FileLoadException.
[ConditionalFact(typeof(TestLibrary.Utilities), nameof(TestLibrary.Utilities.IsNotMonoRuntime), nameof(TestLibrary.Utilities.IsNotNativeAot))]
public static void TestEntryPoint()
{
// Calling the protected Object.MemberwiseClone (defined in a different assembly) forces the
// runtime to run an accessibility check against this assembly, which parses its InternalsVisibleTo
// metadata. Because that metadata is invalid, parsing throws and surfaces the FileLoadException.
FileLoadException exception = Assert.Throws<FileLoadException>(() => new InvalidFriendAssemblyName().GetCopy());
Comment thread
elinor-fung marked this conversation as resolved.

Comment thread
elinor-fung marked this conversation as resolved.
Comment thread
elinor-fung marked this conversation as resolved.
// The outer exception identifies the assembly that declared the invalid friend reference.
Assert.Contains(nameof(InvalidFriendAssemblyName), exception.FileName, StringComparison.Ordinal);

// The inner exception preserves the real cause: the invalid friend assembly name.
FileLoadException inner = Assert.IsType<FileLoadException>(exception.InnerException);
Assert.Equal(InvalidAssemblyName, inner.FileName);
Assert.Contains("assembly name was invalid", inner.Message, StringComparison.OrdinalIgnoreCase);
}

public object GetCopy() => MemberwiseClone();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<Compile Include="InvalidFriendAssemblyName.cs" />
<ProjectReference Include="$(TestLibraryProjectPath)" />
</ItemGroup>
</Project>
Loading