Skip to content

Commit fab6746

Browse files
committed
Change return types of reverse FCalls that return Assembly to RuntimeAssembly to ensure type safety
Fixes #104466
1 parent f63ef6b commit fab6746

File tree

7 files changed

+26
-69
lines changed

7 files changed

+26
-69
lines changed

src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -598,12 +598,12 @@ private CultureInfo GetLocale()
598598
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "AssemblyNative_GetSimpleName")]
599599
private static partial void GetSimpleName(QCallAssembly assembly, StringHandleOnStack retSimpleName);
600600

601-
internal string? GetSimpleName()
601+
internal string GetSimpleName()
602602
{
603603
RuntimeAssembly runtimeAssembly = this;
604604
string? name = null;
605605
GetSimpleName(new QCallAssembly(ref runtimeAssembly), new StringHandleOnStack(ref name));
606-
return name;
606+
return name!;
607607
}
608608

609609
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "AssemblyNative_GetHashAlgorithm")]

src/coreclr/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.CoreCLR.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ internal Assembly LoadFromInMemoryModule(IntPtr moduleHandle)
110110

111111
// This method is invoked by the VM to resolve a satellite assembly reference
112112
// after trying assembly resolution via Load override without success.
113-
private static Assembly? ResolveSatelliteAssembly(IntPtr gchManagedAssemblyLoadContext, AssemblyName assemblyName)
113+
private static RuntimeAssembly? ResolveSatelliteAssembly(IntPtr gchManagedAssemblyLoadContext, AssemblyName assemblyName)
114114
{
115115
AssemblyLoadContext context = (AssemblyLoadContext)(GCHandle.FromIntPtr(gchManagedAssemblyLoadContext).Target)!;
116116

@@ -136,7 +136,7 @@ private static IntPtr ResolveUnmanagedDllUsingEvent(string unmanagedDllName, Ass
136136

137137
// This method is invoked by the VM to resolve an assembly reference using the Resolving event
138138
// after trying assembly resolution via Load override and TPA load context without success.
139-
private static Assembly? ResolveUsingResolvingEvent(IntPtr gchManagedAssemblyLoadContext, AssemblyName assemblyName)
139+
private static RuntimeAssembly? ResolveUsingResolvingEvent(IntPtr gchManagedAssemblyLoadContext, AssemblyName assemblyName)
140140
{
141141
AssemblyLoadContext context = (AssemblyLoadContext)(GCHandle.FromIntPtr(gchManagedAssemblyLoadContext).Target)!;
142142
// Invoke the AssemblyResolve event callbacks if wired up

src/coreclr/vm/corelib.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -863,11 +863,11 @@ DEFINE_FIELD_U(_id, AssemblyLoadContextBaseObject, _id)
863863
DEFINE_FIELD_U(_state, AssemblyLoadContextBaseObject, _state)
864864
DEFINE_FIELD_U(_isCollectible, AssemblyLoadContextBaseObject, _isCollectible)
865865
DEFINE_CLASS(ASSEMBLYLOADCONTEXT, Loader, AssemblyLoadContext)
866-
DEFINE_METHOD(ASSEMBLYLOADCONTEXT, RESOLVE, Resolve, SM_IntPtr_AssemblyName_RetAssemblyBase)
866+
DEFINE_METHOD(ASSEMBLYLOADCONTEXT, RESOLVE, Resolve, SM_IntPtr_AssemblyName_RetAssembly)
867867
DEFINE_METHOD(ASSEMBLYLOADCONTEXT, RESOLVEUNMANAGEDDLL, ResolveUnmanagedDll, SM_Str_IntPtr_RetIntPtr)
868868
DEFINE_METHOD(ASSEMBLYLOADCONTEXT, RESOLVEUNMANAGEDDLLUSINGEVENT, ResolveUnmanagedDllUsingEvent, SM_Str_AssemblyBase_IntPtr_RetIntPtr)
869-
DEFINE_METHOD(ASSEMBLYLOADCONTEXT, RESOLVEUSINGEVENT, ResolveUsingResolvingEvent, SM_IntPtr_AssemblyName_RetAssemblyBase)
870-
DEFINE_METHOD(ASSEMBLYLOADCONTEXT, RESOLVESATELLITEASSEMBLY, ResolveSatelliteAssembly, SM_IntPtr_AssemblyName_RetAssemblyBase)
869+
DEFINE_METHOD(ASSEMBLYLOADCONTEXT, RESOLVEUSINGEVENT, ResolveUsingResolvingEvent, SM_IntPtr_AssemblyName_RetAssembly)
870+
DEFINE_METHOD(ASSEMBLYLOADCONTEXT, RESOLVESATELLITEASSEMBLY, ResolveSatelliteAssembly, SM_IntPtr_AssemblyName_RetAssembly)
871871
DEFINE_FIELD(ASSEMBLYLOADCONTEXT, ASSEMBLY_LOAD, AssemblyLoad)
872872
DEFINE_METHOD(ASSEMBLYLOADCONTEXT, ON_ASSEMBLY_LOAD, OnAssemblyLoad, SM_Assembly_RetVoid)
873873
DEFINE_METHOD(ASSEMBLYLOADCONTEXT, ON_RESOURCE_RESOLVE, OnResourceResolve, SM_Assembly_Str_RetAssembly)

src/coreclr/vm/metasig.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -393,8 +393,6 @@ DEFINE_METASIG(IM(IntPtr_Int_RetVoid, I i, v))
393393
DEFINE_METASIG(IM(IntInt_RetArrByte, i i, a(b)))
394394
DEFINE_METASIG(IM(RetIntPtr, _, I))
395395
DEFINE_METASIG(IM(RetInt, _, i))
396-
DEFINE_METASIG_T(IM(RetAssemblyName, _, C(ASSEMBLY_NAME)))
397-
DEFINE_METASIG_T(IM(RetAssemblyBase, _, C(ASSEMBLYBASE)))
398396
DEFINE_METASIG_T(IM(RetModule, _, C(MODULE)))
399397
DEFINE_METASIG_T(IM(PtrNativeAssemblyNameParts, P(g(NATIVE_ASSEMBLY_NAME_PARTS)), v))
400398
DEFINE_METASIG(SM(PtrCharPtrVoid, P(u) P(v), v))
@@ -456,8 +454,6 @@ DEFINE_METASIG(IM(Int_Int_Int_Int_RetVoid, i i i i, v))
456454
DEFINE_METASIG_T(IM(Obj_EventArgs_RetVoid, j C(EVENT_ARGS), v))
457455
DEFINE_METASIG_T(IM(Obj_UnhandledExceptionEventArgs_RetVoid, j C(UNHANDLED_EVENTARGS), v))
458456

459-
DEFINE_METASIG_T(IM(Assembly_RetBool, C(ASSEMBLY), F))
460-
DEFINE_METASIG_T(IM(AssemblyBase_RetBool, C(ASSEMBLYBASE), F))
461457
DEFINE_METASIG_T(IM(Exception_RetVoid, C(EXCEPTION), v))
462458

463459
DEFINE_METASIG(IM(IntPtr_RetObj, I, j))
@@ -565,7 +561,7 @@ DEFINE_METASIG_T(IM(RefGuid_OutIntPtr_RetCustomQueryInterfaceResult, r(g(GUID))
565561
DEFINE_METASIG_T(SM(RefGuid_RefGuid_RetVoid, r(g(GUID)) r(g(GUID)) , v))
566562
DEFINE_METASIG_T(SM(RefGuid_RetVoid, r(g(GUID)), v))
567563

568-
DEFINE_METASIG_T(SM(IntPtr_AssemblyName_RetAssemblyBase, I C(ASSEMBLY_NAME), C(ASSEMBLYBASE)))
564+
DEFINE_METASIG_T(SM(IntPtr_AssemblyName_RetAssembly, I C(ASSEMBLY_NAME), C(ASSEMBLY)))
569565
DEFINE_METASIG_T(SM(Str_AssemblyBase_IntPtr_RetIntPtr, s C(ASSEMBLYBASE) I, I))
570566
DEFINE_METASIG_T(SM(Str_AssemblyBase_Bool_UInt_RetIntPtr, s C(ASSEMBLYBASE) F K, I))
571567

src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs

Lines changed: 15 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,7 @@ public void Dispose()
609609
#if !NATIVEAOT
610610
// This method is invoked by the VM when using the host-provided assembly load context
611611
// implementation.
612-
private static Assembly? Resolve(IntPtr gchManagedAssemblyLoadContext, AssemblyName assemblyName)
612+
private static RuntimeAssembly? Resolve(IntPtr gchManagedAssemblyLoadContext, AssemblyName assemblyName)
613613
{
614614
AssemblyLoadContext context = (AssemblyLoadContext)(GCHandle.FromIntPtr(gchManagedAssemblyLoadContext).Target)!;
615615

@@ -644,56 +644,44 @@ public void Dispose()
644644
return null;
645645
}
646646

647-
private static Assembly ValidateAssemblyNameWithSimpleName(Assembly assembly, string? requestedSimpleName)
647+
private static RuntimeAssembly ValidateAssemblyNameWithSimpleName(Assembly assembly, string? requestedSimpleName)
648648
{
649649
ArgumentException.ThrowIfNullOrEmpty(requestedSimpleName, "AssemblyName.Name");
650650

651-
// Get the name of the loaded assembly
652-
string? loadedSimpleName = null;
653-
654651
// Derived type's Load implementation is expected to use one of the LoadFrom* methods to get the assembly
655652
// which is a RuntimeAssembly instance. However, since Assembly type can be used build any other artifact (e.g. AssemblyBuilder),
656653
// we need to check for RuntimeAssembly.
657-
RuntimeAssembly? rtLoadedAssembly = GetRuntimeAssembly(assembly);
658-
if (rtLoadedAssembly != null)
654+
RuntimeAssembly? runtimeAssembly = GetRuntimeAssembly(assembly);
655+
if (runtimeAssembly == null)
659656
{
660-
loadedSimpleName = rtLoadedAssembly.GetSimpleName();
657+
throw new InvalidOperationException(SR.Argument_MustBeRuntimeAssembly);
661658
}
662659

663-
// The simple names should match at the very least
664-
if (string.IsNullOrEmpty(loadedSimpleName) || !requestedSimpleName.Equals(loadedSimpleName, StringComparison.InvariantCultureIgnoreCase))
660+
if (!requestedSimpleName.Equals(runtimeAssembly.GetSimpleName(), StringComparison.InvariantCultureIgnoreCase))
665661
{
666662
throw new InvalidOperationException(SR.Argument_CustomAssemblyLoadContextRequestedNameMismatch);
667663
}
668664

669-
return assembly;
665+
return runtimeAssembly;
670666
}
671667

672-
private Assembly? ResolveUsingLoad(AssemblyName assemblyName)
668+
private RuntimeAssembly? ResolveUsingLoad(AssemblyName assemblyName)
673669
{
674670
string? simpleName = assemblyName.Name;
675-
Assembly? assembly = Load(assemblyName);
676671

677-
if (assembly != null)
678-
{
679-
assembly = ValidateAssemblyNameWithSimpleName(assembly, simpleName);
680-
}
672+
Assembly? assembly = Load(assemblyName);
681673

682-
return assembly;
674+
return (assembly != null) ? ValidateAssemblyNameWithSimpleName(assembly, simpleName) : null;
683675
}
684676

685-
private Assembly? ResolveUsingEvent(AssemblyName assemblyName)
677+
private RuntimeAssembly? ResolveUsingEvent(AssemblyName assemblyName)
686678
{
687679
string? simpleName = assemblyName.Name;
688680

689681
// Invoke the Resolving event callbacks if wired up
690682
Assembly? assembly = GetFirstResolvedAssemblyFromResolvingEvent(assemblyName);
691-
if (assembly != null)
692-
{
693-
assembly = ValidateAssemblyNameWithSimpleName(assembly, simpleName);
694-
}
695683

696-
return assembly;
684+
return (assembly != null) ? ValidateAssemblyNameWithSimpleName(assembly, simpleName) : null;
697685
}
698686

699687
// This method is called by the VM.
@@ -760,7 +748,7 @@ internal static void InvokeAssemblyLoadEvent(Assembly assembly)
760748
Justification = "Satellite assemblies have no code in them and loading is not a problem")]
761749
[UnconditionalSuppressMessage("SingleFile", "IL3000: Avoid accessing Assembly file path when publishing as a single file",
762750
Justification = "This call is fine because native call runs before this and checks BindSatelliteResourceFromBundle")]
763-
private Assembly? ResolveSatelliteAssembly(AssemblyName assemblyName)
751+
private RuntimeAssembly? ResolveSatelliteAssembly(AssemblyName assemblyName)
764752
{
765753
// Called by native runtime when CultureName is not empty
766754
Debug.Assert(assemblyName.CultureName?.Length > 0);
@@ -772,7 +760,7 @@ internal static void InvokeAssemblyLoadEvent(Assembly assembly)
772760

773761
string parentAssemblyName = assemblyName.Name.Substring(0, assemblyName.Name.Length - SatelliteSuffix.Length);
774762

775-
Assembly parentAssembly = LoadFromAssemblyName(new AssemblyName(parentAssemblyName));
763+
RuntimeAssembly parentAssembly = (RuntimeAssembly)LoadFromAssemblyName(new AssemblyName(parentAssemblyName));
776764

777765
AssemblyLoadContext parentALC = GetLoadContext(parentAssembly)!;
778766

@@ -795,7 +783,7 @@ internal static void InvokeAssemblyLoadEvent(Assembly assembly)
795783
exists = FileSystem.FileExists(assemblyPath);
796784
}
797785

798-
Assembly? asm = exists ? parentALC.LoadFromAssemblyPath(assemblyPath) : null;
786+
RuntimeAssembly? asm = exists ? (RuntimeAssembly?)parentALC.LoadFromAssemblyPath(assemblyPath) : null;
799787
#if CORECLR
800788
if (IsTracingEnabled())
801789
{

src/mono/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -136,28 +136,6 @@ public override Module ManifestModule
136136
// TODO: consider a dedicated icall instead
137137
public override bool IsCollectible => AssemblyLoadContext.GetLoadContext((Assembly)this)!.IsCollectible;
138138

139-
internal static AssemblyName? CreateAssemblyName(string assemblyString, out RuntimeAssembly? assemblyFromResolveEvent)
140-
{
141-
ArgumentNullException.ThrowIfNull(assemblyString);
142-
143-
if ((assemblyString.Length == 0) ||
144-
(assemblyString[0] == '\0'))
145-
throw new ArgumentException(SR.Format_StringZeroLength);
146-
147-
assemblyFromResolveEvent = null;
148-
try
149-
{
150-
return new AssemblyName(assemblyString);
151-
}
152-
catch (Exception)
153-
{
154-
assemblyFromResolveEvent = (RuntimeAssembly?)AssemblyLoadContext.DoAssemblyResolve(assemblyString);
155-
if (assemblyFromResolveEvent == null)
156-
throw new FileLoadException(assemblyString);
157-
return null;
158-
}
159-
}
160-
161139
[MethodImplAttribute(MethodImplOptions.InternalCall)]
162140
private static extern void GetManifestResourceNames(QCallAssembly assembly_h, ObjectHandleOnStack res);
163141

src/mono/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.Mono.cs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -118,28 +118,23 @@ public void StartProfileOptimization(string? profile)
118118
[MethodImplAttribute(MethodImplOptions.InternalCall)]
119119
private static extern Assembly[] InternalGetLoadedAssemblies();
120120

121-
internal static Assembly? DoAssemblyResolve(string name)
122-
{
123-
return AssemblyResolve?.Invoke(null, new ResolveEventArgs(name));
124-
}
125-
126121
// Invoked by Mono to resolve using the load method.
127-
private static Assembly? MonoResolveUsingLoad(IntPtr gchALC, string assemblyName)
122+
private static RuntimeAssembly? MonoResolveUsingLoad(IntPtr gchALC, string assemblyName)
128123
{
129124
return Resolve(gchALC, new AssemblyName(assemblyName));
130125
}
131126

132127
// Invoked by Mono to resolve using the Resolving event after
133128
// trying the Load override and default load context without
134129
// success.
135-
private static Assembly? MonoResolveUsingResolvingEvent(IntPtr gchALC, string assemblyName)
130+
private static RuntimeAssembly? MonoResolveUsingResolvingEvent(IntPtr gchALC, string assemblyName)
136131
{
137132
AssemblyLoadContext context = GetAssemblyLoadContext(gchALC);
138133
return context.ResolveUsingEvent(new AssemblyName(assemblyName));
139134
}
140135

141136
// Invoked by Mono to resolve requests to load satellite assemblies.
142-
private static Assembly? MonoResolveUsingResolveSatelliteAssembly(IntPtr gchALC, string assemblyName)
137+
private static RuntimeAssembly? MonoResolveUsingResolveSatelliteAssembly(IntPtr gchALC, string assemblyName)
143138
{
144139
AssemblyLoadContext context = GetAssemblyLoadContext(gchALC);
145140
return context.ResolveSatelliteAssembly(new AssemblyName(assemblyName));

0 commit comments

Comments
 (0)