Merge pull request #814 from PowerShell/andschwa/recursive-alc

Fix stack overflow exception when loading assemblies
This commit is contained in:
Andy Schwartzmeyer 2016-04-13 13:54:38 -07:00
commit 2a7d6a51c6

View file

@ -141,9 +141,8 @@ namespace System.Management.Automation
string asmCultureName = assemblyName.CultureName ?? string.Empty; string asmCultureName = assemblyName.CultureName ?? string.Empty;
string asmFilePath = null; 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); string asmCulturePath = Path.Combine(probingPath, asmCultureName);
for (int k = 0; k < extensions.Length; k++) for (int k = 0; k < extensions.Length; k++)
{ {
@ -184,19 +183,21 @@ namespace System.Management.Automation
assemblyName.FullName); assemblyName.FullName);
} }
// Try loading it from the TPA list. All PowerShell dependencies are in the
// TPA list when published with dotnet-cli.
try try
{
asmLoaded = Assembly.Load(assemblyName);
}
// If it wasn't there, try loading from path
catch (FileNotFoundException)
{ {
asmLoaded = asmFilePath.EndsWith(".ni.dll", StringComparison.OrdinalIgnoreCase) asmLoaded = asmFilePath.EndsWith(".ni.dll", StringComparison.OrdinalIgnoreCase)
? LoadFromNativeImagePath(asmFilePath, null) ? LoadFromNativeImagePath(asmFilePath, null)
: LoadFromAssemblyPath(asmFilePath); : 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 it loaded, add it to the cache
if (asmLoaded != null) if (asmLoaded != null)
@ -250,20 +251,22 @@ namespace System.Management.Automation
if (TryGetAssemblyFromCache(assemblyName, out asmLoaded)) if (TryGetAssemblyFromCache(assemblyName, out asmLoaded))
return asmLoaded; return asmLoaded;
// Try loading it from the TPA list. All PowerShell dependencies are in the
// TPA list when published with dotnet-cli.
try try
{
asmLoaded = Assembly.Load(assemblyName);
}
// If it wasn't there, try loading from path
catch (FileNotFoundException)
{ {
// Load the assembly through 'LoadFromNativeImagePath' or 'LoadFromAssemblyPath' // Load the assembly through 'LoadFromNativeImagePath' or 'LoadFromAssemblyPath'
asmLoaded = assemblyPath.EndsWith(".ni.dll", StringComparison.OrdinalIgnoreCase) asmLoaded = assemblyPath.EndsWith(".ni.dll", StringComparison.OrdinalIgnoreCase)
? LoadFromNativeImagePath(assemblyPath, null) ? LoadFromNativeImagePath(assemblyPath, null)
: LoadFromAssemblyPath(assemblyPath); : 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) if (asmLoaded != null)
{ {
@ -503,11 +506,11 @@ namespace System.Management.Automation
// Porting note: it's much easier to send an LPStr on Linux // Porting note: it's much easier to send an LPStr on Linux
private const UnmanagedType stringType = private const UnmanagedType stringType =
#if LINUX #if LINUX
UnmanagedType.LPStr UnmanagedType.LPStr
#else #else
UnmanagedType.LPWStr UnmanagedType.LPWStr
#endif #endif
; ;
/// <summary> /// <summary>