/// <summary> /// Checks assembly for not allowed operations (ie. accesing file system, network) /// </summary> /// <param name="tmpAssembly">output assembly</param> /// <param name="errors">compilation or check errors</param> /// <param name="result">compiled assembly</param> /// <param name="isIngameScript"></param> /// <returns>wheter the check was sucessflu (false AND null asembly on fail)</returns> private static bool CheckResultInternal(out Assembly assembly, List <string> errors, CompilerResults result, bool isIngameScript) { assembly = null; if (result.Errors.HasErrors) { var en = result.Errors.GetEnumerator(); while (en.MoveNext()) { if (!(en.Current as CompilerError).IsWarning) { errors.Add((en.Current as CompilerError).ToString()); } } return(false); } var tmpAssembly = result.CompiledAssembly; Type failedType; var dic = new Dictionary <Type, HashSet <MemberInfo> >(); foreach (var t in tmpAssembly.GetTypes()) //allows calls inside assembly { dic.Add(t, null); } List <MethodBase> typeMethods = new List <MethodBase>(); BindingFlags bfAllMembers = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance; foreach (var t in tmpAssembly.GetTypes()) { typeMethods.Clear(); typeMethods.AddArray(t.GetMethods(bfAllMembers)); typeMethods.AddArray(t.GetConstructors(bfAllMembers)); foreach (var m in typeMethods) { if (IlChecker.IsMethodFromParent(t, m)) { if (IlChecker.CheckTypeAndMember(m.DeclaringType, isIngameScript) == false) { errors.Add(string.Format("Class {0} derives from class {1} that is not allowed in script", t.Name, m.DeclaringType.Name)); return(false); } continue; } if ((!IlChecker.CheckIl(m_reader.ReadInstructions(m), out failedType, isIngameScript, dic)) || IlChecker.HasMethodInvalidAtrributes(m.Attributes)) { // CH: TODO: This message does not make much sense when we test not only allowed types, but also method attributes errors.Add(string.Format("Type {0} used in {1} not allowed in script", failedType == null ? "FIXME" : failedType.ToString(), m.Name)); return(false); } } } assembly = tmpAssembly; return(true); }
public static bool Compile(string[] instructions, out Assembly assembly, bool isIngameScript, bool wrap = true) { //m_options = new System.CodeDom.Compiler.CompilerParameters(new string[] { "Sandbox.Game.dll", "Sandbox.Common.dll", "VRage.Common.dll", "System.Core.dll", "System.dll" }); //m_options.GenerateInMemory = true; assembly = null; m_cache.Clear(); if (wrap) { m_cache.AppendFormat(invokeWrapper, instructions); } else { m_cache.Append(instructions[0]); } var result = m_cp.CompileAssemblyFromSource(Options, m_cache.ToString()); if (result.Errors.HasErrors) { return(false); } assembly = result.CompiledAssembly; Type failedType; var dic = new Dictionary <Type, HashSet <MemberInfo> >(); foreach (var t in assembly.GetTypes()) //allows calls inside assembly { dic.Add(t, null); } foreach (var t in assembly.GetTypes()) { foreach (var m in t.GetMethods()) { if (t == typeof(MulticastDelegate)) { continue; } if (!IlChecker.CheckIl(m_reader.ReadInstructions(m), out failedType, isIngameScript, dic)) { assembly = null; return(false); } } } return(true); }