public static RunResult ExecuteCode(RunOptsBase opts, Type codeHelperType) { AppDomain sandboxDomain = SandboxHelper.CreateSandboxDomain(true, GetMappings()); try { var containerType = typeof(Container); ObjectHandle handle = Activator.CreateInstanceFrom( sandboxDomain, containerType.Assembly.ManifestModule.FullyQualifiedName, containerType.FullName); var container = handle.Unwrap() as Container; container.InitWorkerSettings( WorkerConfiguration.Current.ID, WorkerConfiguration.Current.SandboxFolder, codeHelperType); var runResult = container.Run(opts); return runResult; } finally { SandboxHelper.UnloadDomain(sandboxDomain); } }
public CompilerResults CompileConsole(RunOptsBase opts, int?warningLevel = null, bool loadAssembyToAppDomain = true) { return(CompileCode(new List <string>() { ((ConsoleOrScriptCodeBlock)opts.CodeBlock).CodeBlock }, warningLevel, loadAssembyToAppDomain)); }
protected virtual bool CheckCodeBlock(RunOptsBase opts, ref RunResult runResult) { if (opts.CodeBlock == null) opts.CodeBlock = new ConsoleOrScriptCodeBlock { CodeBlock = string.Empty }; else if (((ConsoleOrScriptCodeBlock)opts.CodeBlock).CodeBlock == null) ((ConsoleOrScriptCodeBlock)opts.CodeBlock).CodeBlock = string.Empty; return CheckCodeSizeLimit(((ConsoleOrScriptCodeBlock)opts.CodeBlock).CodeBlock, ref runResult); }
private void RunConsole(RunOptsBase opts, RunResult result) { new PermissionSet(PermissionState.Unrestricted).Assert(); CompilerResults compilerResults; compilerResults = CompileConsole(opts, 4); if (!IsCompilationSucceed(compilerResults, result)) { PermissionSet.RevertAssert(); return; } MethodInfo mainMethodInfo; object ownerInstance; mainMethodInfo = GetMainMethodAndOwnerInstance(compilerResults.CompiledAssembly, out ownerInstance); if (mainMethodInfo == null || !mainMethodInfo.IsPublic || !mainMethodInfo.DeclaringType.IsPublic) { result.IsSuccess = false; result.FailureType = RunResultFailureType.FatalError; result.FatalErrorMessage = "Public Main() method is required in a public class"; return; } try { this.OnStartingExecution(); PermissionSet.RevertAssert(); //Add timer so doesn't execute for more then 5 secs var paramInfos = mainMethodInfo.GetParameters(); mainMethodInfo.Invoke(ownerInstance, paramInfos.Select(pi => (object)null).ToArray()); this.OnFinishedExecution(); } catch (ThreadAbortException) { throw; } catch (Exception ex) { result.IsSuccess = false; result.FailureType = RunResultFailureType.RunTimeException; result.RunTimeException = new ExceptionInfo(ex.InnerException ?? ex); } finally { result.ConsoleOutput = _consoleWriter.ToString().TrimEnd(); } }
private static RunResult ExecuteCode(RunOptsBase opts, Type codeHelperType, AppDomain sandboxDomain) { Container container = new Container(); container.InitWorkerSettings( WorkerConfiguration.Current.ID, WorkerConfiguration.Current.SandboxFolder, codeHelperType); var runResult = container.Run(opts); return runResult; }
public static RunResult ExecuteCode(RunOptsBase opts, Type codeHelperType) { AppDomain sandboxDomain = SandboxHelper.CreateSandboxDomain(true, GetMappings()); try { return ExecuteCode(opts, codeHelperType, sandboxDomain); } finally { SandboxHelper.UnloadDomain(sandboxDomain); } }
protected override bool CheckCodeBlock(RunOptsBase opts, ref RunResult runResult) { if (opts.CodeBlock == null) opts.CodeBlock = new MvcCodeBlock { Model = string.Empty, View = string.Empty, Controller = string.Empty }; var codeBlock = (MvcCodeBlock) opts.CodeBlock; return CheckCodeSizeLimit(codeBlock.Model, ref runResult) && CheckCodeSizeLimit(codeBlock.Controller, ref runResult); }
public static RunResult RunInThread(CodeHelper codeHelper, RunOptsBase runOpts) { RunResult result = null; try { codeHelper.RequestedConsoleInput += CodeHelper_RequestedConsoleInput; var newThread = new Thread(() => { result = codeHelper.Run(runOpts); }); newThread.Start(); newThread.Join(TimeSpan.FromSeconds(10)); } finally { codeHelper.RequestedConsoleInput -= CodeHelper_RequestedConsoleInput; } return result; }
private static Assembly CurrentDomain_AssemblyResolve(RunOptsBase opts, ResolveEventArgs args) { // when we have different version of the same assembly, we need to map it to that that we already loaded. // for example we use System.Core v4, but AutoMapper requiest System.Core v2.0.5, so we need to map it var ind = args.Name.IndexOf(","); if (ind == -1) { return(null); } var result = SandboxHelper.ExecuteInFullTrust( () => { string name = args.Name.Substring(0, ind); var assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (var assembly in assemblies) { var asName = assembly.GetName().Name; if (asName.Equals(name, StringComparison.CurrentCultureIgnoreCase)) { return(assembly); } } foreach (var reference in opts.NuGetDllReferences) { var fileName = Path.GetFileNameWithoutExtension(reference); if (string.Equals(fileName, name, StringComparison.CurrentCultureIgnoreCase)) { string reference1 = reference; var assembly = Assembly.LoadFile(reference1); return(assembly); } } return(null); }); return(result); }
protected ValidateCodeResult ValidateCodeWithCompilation(string code) { var result = new ValidateCodeResult(); RunOptsBase runOpts = GetRunOpts(code); var compilerResults = CompileConsole(runOpts, 4, false); if (compilerResults.Errors.HasErrors) { result.IsSuccess = false; result.Errors = GetValidationErrorsFromCompilerErrors(compilerResults.Errors); } else { result.IsSuccess = true; // clean up compiled assembly if (File.Exists(compilerResults.PathToAssembly)) { File.Delete(compilerResults.PathToAssembly); } } return(result); }
protected virtual bool VerifyDeniedCodeBlock(RunOptsBase opts, RunResult result) { return(VerifyDeniedCode(((ConsoleOrScriptCodeBlock)opts.CodeBlock).CodeBlock, result)); }
public RunResult Run(RunOptsBase opts) { var result = new RunResult(); result.IsSuccess = true; _consoleReader.InputLines = opts.ConsoleInputLines; if (!VerifyDeniedCodeBlock(opts, result)) { return(result); } ResolveEventHandler handler = (o, e) => CurrentDomain_AssemblyResolve(opts, e); TextWriter defaultConsoleOut = Console.Out; TextReader defaultConsoleIn = Console.In; SandboxHelper.ExecuteInFullTrust( () => { Console.SetOut(_consoleWriter); Console.SetIn(_consoleReader); }); try { AppDomain.CurrentDomain.AssemblyResolve += handler; switch (ProjectType) { case ProjectType.Console: RunConsole(opts, result); break; case ProjectType.Script: RunInteractive(opts, result); break; case ProjectType.Mvc: RunMvc(opts, result); break; default: throw new NotImplementedException(); } } catch (ThreadAbortException ex) { var consoleInputRequest = ex.ExceptionState as ConsoleInputRequest; if (consoleInputRequest != null) { result.IsSuccess = true; result.IsConsoleInputRequested = true; } else { result.IsSuccess = false; var limit = ex.ExceptionState as LimitExceededException; if (limit != null) { result.FailureType = RunResultFailureType.FatalError; result.FatalErrorMessage = LimitExceededException.FormatMessage(limit.LimitType); } } SandboxHelper.ExecuteInFullTrust(Thread.ResetAbort); } finally { //Restore Console Out just in case SandboxHelper.ExecuteInFullTrust( () => { Console.SetOut(defaultConsoleOut); Console.SetIn(defaultConsoleIn); }); // unsubscribe AppDomain.CurrentDomain.AssemblyResolve -= handler; } return(result); }
protected override void RunInteractive(RunOptsBase opts, RunResult result) { new PermissionSet(PermissionState.Unrestricted).Assert(); CommonScriptEngine scriptEngine = this.CreateSciptEngine(); Session session = scriptEngine.CreateSession(); var codeBlock = (ConsoleOrScriptCodeBlock) opts.CodeBlock; var referencedDlls = this.GetGacDlls(codeBlock.CodeBlock); foreach (var referenceDll in referencedDlls) session.AddReference(referenceDll); var libs = GetNonGacDlls(); foreach (var path in libs) { session.AddReference(path); } Submission<object> submission; try { // we compile code there submission = session.CompileSubmission<object>(codeBlock.CodeBlock); } catch (ThreadAbortException) { throw; } catch (Exception ex) { if (!string.IsNullOrEmpty(ex.Message) && ex.Message.Contains(ErrorWhenCompileConsoleProjectAsScript)) {/*Case 4067: DotNetFiddle throws exception on VbNet Script * https://entech.fogbugz.com/default.asp?4067#31607 * This issue occurs, when user is trying to compile VB.Net Console project as VB.Net Script project. * So, there is main entry point 'Module Sub Main' in snippet. * Then Roslyn throws following exception "(3) : error BC35000: Requested operation is not available because the runtime library function 'Microsoft.VisualBasic.CompilerServices.StandardModuleAttribute..ctor' is not defined." * In same case for C#, Roslyn just ignores 'console' code. * So for VB.Net case we just return 'success' and empty string. */ result.IsSuccess = true; result.ConsoleOutput = ""; } else { ValidateCodeResult validateCodeResult = ValidateCode(codeBlock.CodeBlock); result.IsSuccess = false; result.FailureType = RunResultFailureType.CompilerErrors; result.CompilerErrors = validateCodeResult.Errors; } if (result.CompilerErrors == null) { result.CompilerErrors = new List<ValidationError> {ValidationError.CreateFromException(ex)}; } TryCleanRoslynCacheHack(); PermissionSet.RevertAssert(); return; } object execResult = null; try { this.OnStartingExecution(); PermissionSet.RevertAssert(); execResult = submission.Execute(); this.OnFinishedExecution(); } catch (ThreadAbortException) { throw; } catch (Exception ex) { result.IsSuccess = false; result.FailureType = RunResultFailureType.RunTimeException; result.RunTimeException = new ExceptionInfo(ex); } finally { result.ConsoleOutput = _consoleWriter.ToString().TrimEnd(); if (execResult != null) { result.ConsoleOutput += Environment.NewLine; result.ConsoleOutput += "[Return value]: " + execResult; } // don't need it as we modified Roslyn assemblies and made fix in them // TryCleanRoslynCacheHack(); } }
protected virtual RunResult ExecuteCodeBlock(RunOptsBase opts, CodeHelper codeHelper) { RunResult result; result = codeHelper.Run(opts); return result; }
protected virtual void RunMvc(RunOptsBase opts, RunResult result) { throw new NotImplementedException(); }
protected override bool VerifyDeniedCodeBlock(RunOptsBase opts, RunResult result) { var codeBlock = ((NancyFxCodeBlock) opts.CodeBlock); var aggregateCode = codeBlock.Controller + codeBlock.Module; return VerifyDeniedCode(aggregateCode, result); }
public RunResult Execute(RunOptsBase opts, Type codeHelperType) { return ExecuteCode(opts, codeHelperType, sandboxDomain); }
protected abstract void RunInteractive(RunOptsBase opts, RunResult result);
private void RunConsole(RunOptsBase opts, RunResult result) { CompilerResults compilerResults; compilerResults = CompileConsole(opts, 4); RunConsole(compilerResults, result); }
public RunResult Run(RunOptsBase opts) { var result = new RunResult(); result.IsSuccess = true; _consoleReader.InputLines = opts.ConsoleInputLines; if (!VerifyDeniedCodeBlock(opts, result)) { return result; } ResolveEventHandler handler = (o, e) => CurrentDomain_AssemblyResolve(opts, e); TextWriter defaultConsoleOut = Console.Out; TextReader defaultConsoleIn = Console.In; SandboxHelper.ExecuteInFullTrust( () => { Console.SetOut(_consoleWriter); Console.SetIn(_consoleReader); }); try { AppDomain.CurrentDomain.AssemblyResolve += handler; switch (ProjectType) { case ProjectType.Console: RunConsole(opts, result); break; case ProjectType.Script: RunInteractive(opts, result); break; case ProjectType.Mvc: RunMvc(opts, result); break; default: throw new NotImplementedException(); } } catch (ThreadAbortException ex) { var consoleInputRequest = ex.ExceptionState as ConsoleInputRequest; if (consoleInputRequest != null) { result.IsSuccess = true; result.IsConsoleInputRequested = true; } else { result.IsSuccess = false; var limit = ex.ExceptionState as LimitExceededException; if (limit != null) { result.FailureType = RunResultFailureType.FatalError; result.FatalErrorMessage = LimitExceededException.FormatMessage(limit.LimitType); } } SandboxHelper.ExecuteInFullTrust(Thread.ResetAbort); } finally { //Restore Console Out just in case SandboxHelper.ExecuteInFullTrust( () => { Console.SetOut(defaultConsoleOut); Console.SetIn(defaultConsoleIn); }); // unsubscribe AppDomain.CurrentDomain.AssemblyResolve -= handler; } return result; }
protected virtual void RunNancyFx(RunOptsBase opts, RunResult result) { CompilerResults compilerResults; compilerResults = CompileNancyFx(opts, 4); RunConsole(compilerResults, result); }
protected override CompilerResults CompileNancyFx(RunOptsBase opts, int? warningLevel = null, bool loadAssembyToAppDomain = true) { CompilerResults result; var nancyFxRunOpts = (NancyFxRunOpts)opts; var codeBlock = ((NancyFxCodeBlock) opts.CodeBlock); List<string> CodeBlocks = new List<string>() { NancySelfHostingHelper.Instance.GenerateNancySelfHostingCode(nancyFxRunOpts.HostIndex), codeBlock.Controller, codeBlock.Module, }; //ToDo: Add view as embded resources to assembly??? if (!string.IsNullOrEmpty(codeBlock.View)) { lock (SyncObj) { string path = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), @"index.html"); // Write the stream contents to a new file named "index.html". using (StreamWriter outfile = new StreamWriter(path)) { outfile.Write(codeBlock.View); } result = CompileCode( CodeBlocks, new List<string>(){path}, warningLevel, loadAssembyToAppDomain); } } else { result = CompileCode( CodeBlocks, null, warningLevel, loadAssembyToAppDomain); } return result; }
public RunResult Run(RunOptsBase opts) { RunResult result = null; if (!CheckCodeBlock(opts, ref result)) return result; // we should copy it before running, becuase it can be changed during execution var sandboxFolder = _sandboxFolder; var codeHelper = SandboxHelper.ExecuteInFullTrust(() =>(CodeHelper)Activator.CreateInstance(_codeHelperType)); codeHelper.NuGetDllReferences = opts.NuGetDllReferences; codeHelper.StartingExecution += this.CodeHelper_StartingExecution; codeHelper.FinishedExecution += this.CodeHelper_FinishedExecution; codeHelper.RequestedConsoleInput += this.CodeHelper_RequestedConsoleInput; _executingThread = new Thread( () => { try { _runAt = DateTime.Now; result = this.ExecuteCodeBlock(opts, codeHelper); } finally { // in theory in can be null at this point if something bad happened.... if (result == null) { result = new RunResult() { FailureType = RunResultFailureType.FatalError, IsSuccess = false }; } result.Stats = SandboxHelper.ExecuteInFullTrust(() => GatherStatistics()); _compilationCompleted.Set(); } }); _executingThread.Start(); var monitoringTask = Task.Factory.StartNew(MonitorHealth, _tokenSource.Token); // wait for compilation. Just to be sure we have 15 seconds timeout _compilationCompleted.WaitOne(TimeSpan.FromSeconds(15)); // if something happened during compilation, then we fire _compilationCompleted on exit, and result will be filled, so we just need to return it if (result != null) { return result; } // it will use some time for compilation // it can hungs for some unmanaged call like Console.ReadKey(), so we wait with timeout // we might need to rewrite it to ManualEvent that will be fired when CodeHelper starts execution _executingThread.Join(WorkerConfiguration.Current.ExecutionLimitTimeoutMs * 2); _tokenSource.Cancel(); // we can't move it to new method, as it can be executed via reflection SandboxHelper.ExecuteInFullTrust( () => { try { if (Directory.Exists(sandboxFolder)) { foreach (var file in Directory.EnumerateFiles(sandboxFolder, "*", SearchOption.AllDirectories)) { File.Delete(file); } } } catch { if (result != null) result.SandboxUnloadReason = SandboxUnloadReason.ClearDirFailed; } }); return result; }
public CompilerResults CompileConsole(RunOptsBase opts, int? warningLevel = null, bool loadAssembyToAppDomain = true) { return CompileCode(new List<string>() {((ConsoleOrScriptCodeBlock) opts.CodeBlock).CodeBlock}, warningLevel, loadAssembyToAppDomain); }
private static Assembly CurrentDomain_AssemblyResolve(RunOptsBase opts, ResolveEventArgs args) { // when we have different version of the same assembly, we need to map it to that that we already loaded. // for example we use System.Core v4, but AutoMapper requiest System.Core v2.0.5, so we need to map it var ind = args.Name.IndexOf(","); if (ind == -1) return null; var result = SandboxHelper.ExecuteInFullTrust( () => { string name = args.Name.Substring(0, ind); var assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (var assembly in assemblies) { var asName = assembly.GetName().Name; if (asName.Equals(name, StringComparison.CurrentCultureIgnoreCase)) { return assembly; } } foreach (var reference in opts.NuGetDllReferences) { var fileName = Path.GetFileNameWithoutExtension(reference); if (string.Equals(fileName, name, StringComparison.CurrentCultureIgnoreCase)) { string reference1 = reference; var assembly = Assembly.LoadFile(reference1); return assembly; } } return null; }); return result; }
protected virtual bool VerifyDeniedCodeBlock(RunOptsBase opts, RunResult result) { return VerifyDeniedCode(((ConsoleOrScriptCodeBlock) opts.CodeBlock).CodeBlock, result); }
protected virtual CompilerResults CompileNancyFx(RunOptsBase opts, int? warningLevel = null, bool loadAssembyToAppDomain = true) { throw new NotImplementedException(); }