From dcb2a61ca84347eba30f7ca0fe91ac45360e8ce9 Mon Sep 17 00:00:00 2001 From: jfrijters Date: Tue, 11 May 2010 09:34:58 +0000 Subject: [PATCH] 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). --- ikvmc/AssemblyResolver.cs | 30 ++++++++++++++++++++++++------ ikvmc/Compiler.cs | 7 +++---- ikvmc/CompilerClassLoader.cs | 3 ++- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/ikvmc/AssemblyResolver.cs b/ikvmc/AssemblyResolver.cs index d990920d..c93c0e10 100644 --- a/ikvmc/AssemblyResolver.cs +++ b/ikvmc/AssemblyResolver.cs @@ -33,6 +33,7 @@ namespace IKVM.Internal { private readonly List libpath = new List(); 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: diff --git a/ikvmc/Compiler.cs b/ikvmc/Compiler.cs index 87da0fed..cfadc30d 100644 --- a/ikvmc/Compiler.cs +++ b/ikvmc/Compiler.cs @@ -46,7 +46,6 @@ class IkvmcCompiler private static string runtimeAssembly; private static bool nostdlib; private static readonly List libpaths = new List(); - private static readonly AssemblyResolver loader = new AssemblyResolver(); private static List 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; diff --git a/ikvmc/CompilerClassLoader.cs b/ikvmc/CompilerClassLoader.cs index 8571063d..06bb96ed 100644 --- a/ikvmc/CompilerClassLoader.cs +++ b/ikvmc/CompilerClassLoader.cs @@ -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)