Fix stack overflow exception when loading assemblies
When an assembly that exists outside of the trusted platform assembly list but in the GAC on Windows was loaded, the use of `Assembly.Load` before the `LoadFromAssemblyPath` caused a recursive loop to occur. This happens because an `Assembly.Load` on a not-yet-loaded assembly is overridden, thus calling back into the `AssemblyLoadContext.Load` override. By attempting to load from the file path first, we avoid this loop. However, loading TPA assemblies by their path throws an exception, so now we catch this particular exception and attempt the load through `Assembly.Load`. This is safe for TPA assemblies since they're already loaded, thus the `Assembly.Load` does not re-load the assembly, but simply returns it.
This commit is contained in:
parent
ceef777d5e
commit
1bc2a9e576
|
@ -141,9 +141,8 @@ namespace System.Management.Automation
|
|||
string asmCultureName = assemblyName.CultureName ?? string.Empty;
|
||||
string asmFilePath = null;
|
||||
|
||||
for (int i = 0; i < probingPaths.Count; i++)
|
||||
foreach (var probingPath in probingPaths)
|
||||
{
|
||||
string probingPath = probingPaths[i];
|
||||
string asmCulturePath = Path.Combine(probingPath, asmCultureName);
|
||||
for (int k = 0; k < extensions.Length; k++)
|
||||
{
|
||||
|
@ -184,19 +183,21 @@ namespace System.Management.Automation
|
|||
assemblyName.FullName);
|
||||
}
|
||||
|
||||
// Try loading it from the TPA list. All PowerShell dependencies are in the
|
||||
// TPA list when published with dotnet-cli.
|
||||
try
|
||||
{
|
||||
asmLoaded = Assembly.Load(assemblyName);
|
||||
}
|
||||
// If it wasn't there, try loading from path
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
asmLoaded = asmFilePath.EndsWith(".ni.dll", StringComparison.OrdinalIgnoreCase)
|
||||
? LoadFromNativeImagePath(asmFilePath, null)
|
||||
: LoadFromAssemblyPath(asmFilePath);
|
||||
}
|
||||
// Since .NET CLI built versions of PowerShell have all the
|
||||
// built-in assemblies in the TPA list, the above will throw,
|
||||
// and we have to use Assembly.Load. However, we must try the
|
||||
// above first, otherwise assemblies that exist outside the TPA
|
||||
// list will go into a recursive loop.
|
||||
catch (System.IO.FileLoadException)
|
||||
{
|
||||
asmLoaded = System.Reflection.Assembly.Load(assemblyName);
|
||||
}
|
||||
|
||||
// If it loaded, add it to the cache
|
||||
if (asmLoaded != null)
|
||||
|
@ -250,20 +251,22 @@ namespace System.Management.Automation
|
|||
if (TryGetAssemblyFromCache(assemblyName, out asmLoaded))
|
||||
return asmLoaded;
|
||||
|
||||
// Try loading it from the TPA list. All PowerShell dependencies are in the
|
||||
// TPA list when published with dotnet-cli.
|
||||
try
|
||||
{
|
||||
asmLoaded = Assembly.Load(assemblyName);
|
||||
}
|
||||
// If it wasn't there, try loading from path
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
// Load the assembly through 'LoadFromNativeImagePath' or 'LoadFromAssemblyPath'
|
||||
asmLoaded = assemblyPath.EndsWith(".ni.dll", StringComparison.OrdinalIgnoreCase)
|
||||
? LoadFromNativeImagePath(assemblyPath, null)
|
||||
: LoadFromAssemblyPath(assemblyPath);
|
||||
}
|
||||
// Since .NET CLI built versions of PowerShell have all the
|
||||
// built-in assemblies in the TPA list, the above will throw,
|
||||
// and we have to use Assembly.Load. However, we must try the
|
||||
// above first, otherwise assemblies that exist outside the TPA
|
||||
// list will go into a recursive loop.
|
||||
catch (System.IO.FileLoadException)
|
||||
{
|
||||
asmLoaded = System.Reflection.Assembly.Load(assemblyName);
|
||||
}
|
||||
|
||||
if (asmLoaded != null)
|
||||
{
|
||||
|
@ -503,11 +506,11 @@ namespace System.Management.Automation
|
|||
|
||||
// Porting note: it's much easier to send an LPStr on Linux
|
||||
private const UnmanagedType stringType =
|
||||
#if LINUX
|
||||
#if LINUX
|
||||
UnmanagedType.LPStr
|
||||
#else
|
||||
#else
|
||||
UnmanagedType.LPWStr
|
||||
#endif
|
||||
#endif
|
||||
;
|
||||
|
||||
/// <summary>
|
||||
|
|
Loading…
Reference in a new issue