Added check to avoid loading assemblies that require a newer version of mscorlib than the one were using (to avoid weird exceptions and potential other problems).

This commit is contained in:
jfrijters 2010-05-11 09:34:58 +00:00
Родитель 369efbfb93
Коммит dcb2a61ca8
3 изменённых файлов: 29 добавлений и 11 удалений

Просмотреть файл

@ -33,6 +33,7 @@ namespace IKVM.Internal
{
private readonly List<string> libpath = new List<string>();
private Universe universe;
private Version mscorlibVersion;
internal delegate void HigherVersionEvent(AssemblyName assemblyDef, AssemblyName assemblyRef);
internal event HigherVersionEvent HigherVersion;
@ -60,16 +61,32 @@ namespace IKVM.Internal
}
if (rc == 0)
{
mscorlibVersion = universe.Load("mscorlib").GetName().Version;
universe.AssemblyResolve += new IKVM.Reflection.ResolveEventHandler(universe_AssemblyResolve);
}
return rc;
}
internal Assembly LoadFile(string path)
{
Assembly asm = universe.LoadFile(path);
// to avoid problems (i.e. weird exceptions), we don't allow assemblies to load that reference a newer version of mscorlib
foreach (AssemblyName asmref in asm.GetReferencedAssemblies())
{
if (asmref.Name == "mscorlib" && asmref.Version > mscorlibVersion)
{
Console.Error.WriteLine("Error: unable to load assembly '{0}' as it depends on a higher version of mscorlib than the one currently loaded", path);
Environment.Exit(1);
}
}
return asm;
}
internal Assembly LoadWithPartialName(string name)
{
foreach (string path in FindAssemblyPath(name + ".dll"))
{
return universe.LoadFile(path);
return LoadFile(path);
}
return null;
}
@ -98,7 +115,7 @@ namespace IKVM.Internal
{
foreach (string found in FindAssemblyPath(reference))
{
asm = universe.LoadFile(found);
asm = LoadFile(found);
cache.Add(reference, asm);
break;
}
@ -123,7 +140,7 @@ namespace IKVM.Internal
Assembly asm;
if (!cache.TryGetValue(file, out asm))
{
asm = universe.LoadFile(file);
asm = LoadFile(file);
}
ArrayAppend(ref references, asm);
}
@ -175,7 +192,7 @@ namespace IKVM.Internal
{
if (partialName || Match(AssemblyName.GetAssemblyName(file), name, ref previousMatch, ref previousMatchLevel))
{
return universe.LoadFile(file);
return LoadFile(file);
}
}
if (args.RequestingAssembly != null)
@ -183,7 +200,7 @@ namespace IKVM.Internal
string path = Path.Combine(Path.GetDirectoryName(args.RequestingAssembly.Location), name.Name + ".dll");
if (File.Exists(path) && Match(AssemblyName.GetAssemblyName(path), name, ref previousMatch, ref previousMatchLevel))
{
return universe.LoadFile(path);
return LoadFile(path);
}
}
if (previousMatch != null)
@ -194,7 +211,7 @@ namespace IKVM.Internal
{
HigherVersion(previousMatch, name);
}
return universe.LoadFile(new Uri(previousMatch.CodeBase).LocalPath);
return LoadFile(new Uri(previousMatch.CodeBase).LocalPath);
}
else if (args.RequestingAssembly != null)
{
@ -217,6 +234,7 @@ namespace IKVM.Internal
return null;
}
// TODO this method should be based on Fusion's CompareAssemblyIdentity (which we should have an equivalent of in Universe)
private static bool Match(AssemblyName assemblyDef, AssemblyName assemblyRef, ref AssemblyName bestMatch, ref int bestMatchLevel)
{
// Match levels:

Просмотреть файл

@ -46,7 +46,6 @@ class IkvmcCompiler
private static string runtimeAssembly;
private static bool nostdlib;
private static readonly List<string> libpaths = new List<string>();
private static readonly AssemblyResolver loader = new AssemblyResolver();
private static List<string> GetArgs(string[] args)
{
@ -94,8 +93,8 @@ class IkvmcCompiler
int rc = comp.ParseCommandLine(argList.GetEnumerator(), targets, toplevel);
if (rc == 0)
{
loader.HigherVersion += new AssemblyResolver.HigherVersionEvent(loader_HigherVersion);
rc = loader.Init(StaticCompiler.Universe, nostdlib, toplevel.unresolvedReferences, libpaths);
StaticCompiler.Resolver.HigherVersion += new AssemblyResolver.HigherVersionEvent(loader_HigherVersion);
rc = StaticCompiler.Resolver.Init(StaticCompiler.Universe, nostdlib, toplevel.unresolvedReferences, libpaths);
}
if (rc == 0)
{
@ -874,7 +873,7 @@ class IkvmcCompiler
goto next_reference;
}
}
int rc = loader.ResolveReference(cache, ref target.references, reference);
int rc = StaticCompiler.Resolver.ResolveReference(cache, ref target.references, reference);
if (rc != 0)
{
return rc;

Просмотреть файл

@ -3190,6 +3190,7 @@ namespace IKVM.Internal
static class StaticCompiler
{
internal static readonly Universe Universe = new Universe();
internal static readonly AssemblyResolver Resolver = new AssemblyResolver();
internal static Assembly runtimeAssembly;
internal static Assembly runtimeJniAssembly;
@ -3200,7 +3201,7 @@ namespace IKVM.Internal
internal static Assembly LoadFile(string path)
{
return Universe.LoadFile(path);
return Resolver.LoadFile(path);
}
internal static Type GetRuntimeType(string name)