diff --git a/OpenRA.FileFormats/OpenRA.FileFormats.csproj b/OpenRA.FileFormats/OpenRA.FileFormats.csproj
index b43681e54b..4f62c1e8ce 100644
--- a/OpenRA.FileFormats/OpenRA.FileFormats.csproj
+++ b/OpenRA.FileFormats/OpenRA.FileFormats.csproj
@@ -97,7 +97,6 @@
-
diff --git a/OpenRA.FileFormats/Verifier.cs b/OpenRA.FileFormats/Verifier.cs
deleted file mode 100644
index 417b28b27b..0000000000
--- a/OpenRA.FileFormats/Verifier.cs
+++ /dev/null
@@ -1,207 +0,0 @@
-#region Copyright & License Information
-/*
- * Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
- * This file is part of OpenRA.
- *
- * OpenRA is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * OpenRA is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with OpenRA. If not, see .
- */
-#endregion
-
-using System;
-using System.Reflection;
-using System.Collections.Generic;
-using System.Reflection.Emit;
-using System.Linq;
-
-namespace OpenRA.FileFormats
-{
- public static class Verifier
- {
- static readonly string[] AllowedPatterns = {
- "System.Collections.Generic.*",
- "System.Linq.*",
- "OpenRA.*",
- "System.Collections.*",
- "System.Func*",
- "System.String:*",
- "System.IDisposable:*",
- "System.Action*",
- "System.Object:*",
- "System.Math:*",
- "System.Predicate*",
- "System.NotSupportedException:.ctor",
- "System.Threading.Thread:get_CurrentThread",
- "System.Threading.Thread:get_ManagedThreadId",
-
- // Fixes to let the game run: should be checked by someone knowledgeable
- "System.Threading.Interlocked:CompareExchange",
- "System.Drawing.Color:*",
- };
-
- public static bool IsSafe(string filename, List failures)
- {
- Log.Write("Start verification: {0}", filename);
-
- AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += (s, a) => Assembly.ReflectionOnlyLoad(a.Name);
- var flags = BindingFlags.Instance | BindingFlags.Static |
- BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly;
-
- var assembly = Assembly.ReflectionOnlyLoadFrom(filename);
-
- var pinvokes = assembly.GetTypes()
- .SelectMany(t => t.GetMethods(flags))
- .Where(m => (m.Attributes & MethodAttributes.PinvokeImpl) != 0)
- .Select(m => m.Name).ToArray();
-
- foreach (var pi in pinvokes)
- failures.Add("P/Invoke: {0}".F(pi));
-
- foreach (var fn in assembly
- .GetTypes()
- .SelectMany(x => x.GetMembers(flags))
- .SelectMany(x => FunctionsUsedBy(x))
- .Where(x => x.DeclaringType.Assembly != assembly)
- .Select(x => string.Format("{0}:{1}", x.DeclaringType.FullName, x.Name))
- .OrderBy(x => x)
- .Distinct())
- if (!IsAllowed(fn))
- failures.Add("Unsafe function: {0}".F(fn));
-
- return failures.Count == 0;
- }
-
- static bool IsAllowed(string fn)
- {
- foreach (var p in AllowedPatterns)
- if (p.EndsWith("*"))
- {
- if (fn.StartsWith(p.Substring(0, p.Length - 1))) return true;
- }
- else
- {
- if (fn == p) return true;
- }
-
- Log.Write(fn);
-
- return false;
- }
-
- static IEnumerable FunctionsUsedBy( MemberInfo x )
- {
- if( x is MethodInfo )
- {
- var method = x as MethodInfo;
- if (method.GetMethodBody() != null)
- foreach( var fn in CheckIL( method.GetMethodBody().GetILAsByteArray(), x.Module, x.DeclaringType.GetGenericArguments(), method.GetGenericArguments() ) )
- yield return fn;
- }
- else if( x is ConstructorInfo )
- {
- var method = x as ConstructorInfo;
- if (method.GetMethodBody() != null)
- foreach( var fn in CheckIL( method.GetMethodBody().GetILAsByteArray(), x.Module, x.DeclaringType.GetGenericArguments(), new Type[ 0 ] ) )
- yield return fn;
- }
- else if( x is FieldInfo )
- {
- // ignore it
- }
- else if( x is PropertyInfo )
- {
- var prop = x as PropertyInfo;
- foreach( var method in prop.GetAccessors() )
- if (method.GetMethodBody() != null)
- foreach( var fn in CheckIL( method.GetMethodBody().GetILAsByteArray(), x.Module, x.DeclaringType.GetGenericArguments(), new Type[ 0 ] ) )
- yield return fn;
- }
- else if( x is Type )
- {
- // ... shouldn't happen, but does.... :O
- }
- else
- throw new NotImplementedException();
- }
-
- static IEnumerable CheckIL( byte[] p, Module a, Type[] classGenerics, Type[] functionGenerics )
- {
- var position = 0;
- var ret = new List();
- while( position < p.Length )
- {
- var opcode = OpCodeMap.GetOpCode( p, position );
- position += opcode.Size;
- if( opcode.OperandType == OperandType.InlineMethod )
- ret.Add( BitConverter.ToInt32( p, position ));
- position += OperandSize( opcode, p, position );
- }
- return ret.Select( t => a.ResolveMethod( t, classGenerics, functionGenerics ) );
- }
-
- static int OperandSize( OpCode opcode, byte[] p, int position )
- {
- switch( opcode.OperandType )
- {
- case OperandType.InlineNone:
- return 0;
- case OperandType.InlineMethod:
- case OperandType.InlineField:
- case OperandType.InlineType:
- case OperandType.InlineTok:
- case OperandType.InlineString:
- case OperandType.InlineI:
- case OperandType.InlineBrTarget:
- return 4;
- case OperandType.ShortInlineBrTarget:
- case OperandType.ShortInlineI:
- case OperandType.ShortInlineVar:
- return 1;
- case OperandType.InlineSwitch:
- var numSwitchArgs = BitConverter.ToUInt32( p, position );
- return (int)( 4 + 4 * numSwitchArgs );
- case OperandType.ShortInlineR:
- return 4;
- default:
- throw new NotImplementedException("Unsupported: {0}".F(opcode.OperandType));
- }
- }
- }
-
- static class OpCodeMap
- {
- static readonly Dictionary simpleOps = new Dictionary();
- static readonly Dictionary feOps = new Dictionary();
-
- static OpCodeMap()
- {
- foreach( var o in typeof( OpCodes ).GetFields( BindingFlags.Static | BindingFlags.Public ).Select( f => (OpCode)f.GetValue( null ) ) )
- {
- if( o.Size == 1 )
- simpleOps.Add( (byte)o.Value, o );
- else if( o.Size == 2 )
- feOps.Add( (byte)( o.Value & 0xFF ), o );
- else
- throw new NotImplementedException();
- }
- }
-
- public static OpCode GetOpCode( byte[] input, int position )
- {
- if( input[ position ] != 0xFE )
- return simpleOps[ input[ position ] ];
- else
- return feOps[ input[ position + 1 ] ];
- }
- }
-}
diff --git a/OpenRA.Game/Game.cs b/OpenRA.Game/Game.cs
index ac42f3d285..6112e56493 100644
--- a/OpenRA.Game/Game.cs
+++ b/OpenRA.Game/Game.cs
@@ -79,19 +79,9 @@ namespace OpenRA
{
var failures = new List();
var fullpath = Path.GetFullPath(a);
- if (Verifier.IsSafe(fullpath, failures))
- {
- var asm = Assembly.LoadFile(fullpath);
- asms.AddRange(asm.GetNamespaces().Select(ns => Pair.New(asm, ns)));
- }
- else
- {
- Log.Write("Assembly `{0}` cannot be verified. Failures:", a);
- foreach (var f in failures)
- Log.Write("\t{0}", f);
- throw new InvalidOperationException("Failed verification. See the log for further details.");
- }
+ var asm = Assembly.LoadFile(fullpath);
+ asms.AddRange(asm.GetNamespaces().Select(ns => Pair.New(asm, ns)));
}
ModAssemblies = asms.ToArray();