Skip to content

Commit

Permalink
Sandbox concept.
Browse files Browse the repository at this point in the history
  • Loading branch information
neolithos committed Jan 25, 2015
1 parent 1b190d8 commit b74aca9
Show file tree
Hide file tree
Showing 7 changed files with 194 additions and 91 deletions.
6 changes: 3 additions & 3 deletions NeoCmd/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ protected override void OnFrameExit()

private static Lua lua = new Lua(); // create lua script compiler
private static LuaGlobal global;
private static ILuaDebug debugEngine = Lua.DefaultDebugEngine;
private static ILuaDebug debugEngine = Lua.DefaultDebugEngine.DebugEngine;
private static ILuaDebug debugConsole = new LuaTraceLineConsoleDebugger();

private static void WriteText(ConsoleColor textColor, string sText)
Expand Down Expand Up @@ -423,7 +423,7 @@ private static void RunScript(Func<string> code, string sName)
sw.Start();

// compile chunk
LuaChunk c = lua.CompileChunk(code(), sName, debugEngine);
LuaChunk c = lua.CompileChunk(code(), sName, new LuaCompileOptions() { DebugEngine = debugEngine });

string sCompileTime = String.Format("{0:N0} ms", sw.ElapsedMilliseconds);
sw.Reset();
Expand Down Expand Up @@ -548,7 +548,7 @@ public static void Main(string[] args)
else if (sLine == Boolean.TrueString)
{
WriteText(ConsoleColor.DarkYellow, "Compile emits stack trace information and runtime functions, now."); Console.WriteLine();
debugEngine = Lua.DefaultDebugEngine;
debugEngine = Lua.DefaultDebugEngine.DebugEngine;
}
else
{
Expand Down
111 changes: 92 additions & 19 deletions NeoLua/Lua.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,76 @@ public enum LuaFloatType : byte

#endregion

#region -- enum LuaSandboxResult ----------------------------------------------------

///////////////////////////////////////////////////////////////////////////////
/// <summary>Defines the sandbox type</summary>
public enum LuaSandboxResult
{
/// <summary>No sandbox</summary>
None,
/// <summary>Access is not allowed.</summary>
Restrict,
/// <summary>Check the access during runtime.</summary>
Dynamic
} // enum LuaSandboxResult

#endregion

#region -- class LuaCompileOptions --------------------------------------------------

///////////////////////////////////////////////////////////////////////////////
/// <summary>Defines option for the parse and compile of a script.</summary>
public class LuaCompileOptions
{
/// <summary>Action on access diened.</summary>
/// <returns></returns>
protected virtual Expression RestrictAccess()
{
return Expression.Throw(Expression.New(typeof(UnauthorizedAccessException)));
} // func RestrictAccess

/// <summary>Most core method, that gets called to sandbox a value.</summary>
/// <param name="expression">Expression, that should be sandboxed.</param>
/// <param name="instance">Optional: Instance, that was called to get the expression.</param>
/// <param name="sMember">Optional: Name of the member that was used to resolve the expression.</param>
/// <returns>Sandboxed expression</returns>
protected internal virtual Expression SandboxCore(Expression expression, Expression instance, string sMember)
{
switch (Sandbox(expression.Type, instance == null ? null : instance.Type, sMember))
{
case LuaSandboxResult.Dynamic:
if (DynamicSandbox == null)
return expression;
else
return LuaEmit.Convert(null, Expression.Invoke(Expression.Constant(DynamicSandbox), expression), typeof(object), expression.Type, false);

case LuaSandboxResult.Restrict:
return RestrictAccess();

default:
return expression;
}
} // func SandboxCore

/// <summary>Higher level method to restict access to types.</summary>
/// <param name="expressionType">Type of the sandbox value</param>
/// <param name="instanceType">Optional: Instance, that was called to get the expression.</param>
/// <param name="sMember">Optional: Name of the member that was used to resolve the expression.</param>
/// <returns>Sandbox action</returns>
protected virtual LuaSandboxResult Sandbox(Type expressionType, Type instanceType, string sMember)
{
return DynamicSandbox == null ? LuaSandboxResult.None : LuaSandboxResult.Dynamic;
} // func Sandbox

/// <summary>Gets called if the sandbox will resolved during runtime.</summary>
public Func<object, object> DynamicSandbox { get; set; }
/// <summary>Set this member to compile the script with Debug-Infos.</summary>
public ILuaDebug DebugEngine { get; set; }
} // class LuaCompileOptions

#endregion

///////////////////////////////////////////////////////////////////////////////
/// <summary>Manages the Lua-Script-Environment. At the time it holds the
/// binder cache between the compiled scripts.</summary>
Expand Down Expand Up @@ -106,48 +176,51 @@ public virtual void Clear()

/// <summary>Erzeugt ein Delegate aus dem Code, ohne ihn auszuführen.</summary>
/// <param name="sFileName">Dateiname die gelesen werden soll.</param>
/// <param name="debug">Compile with debug infos</param>
/// <param name="options">Options for the compile process.</param>
/// <param name="args">Parameter für den Codeblock</param>
/// <returns>Compiled chunk.</returns>
public LuaChunk CompileChunk(string sFileName, ILuaDebug debug, params KeyValuePair<string, Type>[] args)
public LuaChunk CompileChunk(string sFileName, LuaCompileOptions options, params KeyValuePair<string, Type>[] args)
{
return CompileChunk(sFileName, debug, new StreamReader(sFileName), args);
return CompileChunk(sFileName, options, new StreamReader(sFileName), args);
} // func CompileChunk

/// <summary>Erzeugt ein Delegate aus dem Code, ohne ihn auszuführen.</summary>
/// <param name="tr">Inhalt</param>
/// <param name="sName">Name der Datei</param>
/// <param name="debug">Compile with debug infos</param>
/// <param name="options">Options for the compile process.</param>
/// <param name="args">Parameter für den Codeblock</param>
/// <returns>Compiled chunk.</returns>
public LuaChunk CompileChunk(TextReader tr, string sName, ILuaDebug debug, params KeyValuePair<string, Type>[] args)
public LuaChunk CompileChunk(TextReader tr, string sName, LuaCompileOptions options, params KeyValuePair<string, Type>[] args)
{
return CompileChunk(sName, debug, tr, args);
return CompileChunk(sName, options, tr, args);
} // func CompileChunk

/// <summary>Erzeugt ein Delegate aus dem Code, ohne ihn auszuführen.</summary>
/// <param name="sCode">Code, der das Delegate darstellt.</param>
/// <param name="sName">Name des Delegates</param>
/// <param name="debug">Compile with debug infos</param>
/// <param name="options">Options for the compile process.</param>
/// <param name="args">Argumente</param>
/// <returns>Compiled chunk.</returns>
public LuaChunk CompileChunk(string sCode, string sName, ILuaDebug debug, params KeyValuePair<string, Type>[] args)
public LuaChunk CompileChunk(string sCode, string sName, LuaCompileOptions options, params KeyValuePair<string, Type>[] args)
{
return CompileChunk(sName, debug, new StringReader(sCode), args);
return CompileChunk(sName, options, new StringReader(sCode), args);
} // func CompileChunk

internal LuaChunk CompileChunk(string sChunkName, ILuaDebug debug, TextReader tr, IEnumerable<KeyValuePair<string, Type>> args)
internal LuaChunk CompileChunk(string sChunkName, LuaCompileOptions options, TextReader tr, IEnumerable<KeyValuePair<string, Type>> args)
{
if (String.IsNullOrEmpty(sChunkName))
throw new ArgumentNullException("chunkname");
if (options == null)
options = new LuaCompileOptions();

using (LuaLexer l = new LuaLexer(sChunkName, tr))
{
if (debug != null && (debug.Level & LuaDebugLevel.RegisterMethods) == LuaDebugLevel.RegisterMethods)
bool lRegisterMethods = options.DebugEngine != null && (options.DebugEngine.Level & LuaDebugLevel.RegisterMethods) == LuaDebugLevel.RegisterMethods;
if (lRegisterMethods)
BeginCompile();
try
{
LambdaExpression expr = Parser.ParseChunk(this, debug == null ? LuaDebugLevel.None : debug.Level, true, l, null, typeof(LuaResult), args);
LambdaExpression expr = Parser.ParseChunk(this, options, true, l, null, typeof(LuaResult), args);

if (lPrintExpressionTree)
{
Expand All @@ -156,14 +229,14 @@ internal LuaChunk CompileChunk(string sChunkName, ILuaDebug debug, TextReader tr
}

// compile the chunk
if (debug == null)
if (options.DebugEngine == null)
return new LuaChunk(this, expr.Name, expr.Compile());
else
return debug.CreateChunk(this, expr);
return options.DebugEngine.CreateChunk(this, expr);
}
finally
{
if (debug != null && (debug.Level & LuaDebugLevel.RegisterMethods) == LuaDebugLevel.RegisterMethods)
if (lRegisterMethods)
EndCompile();
}
}
Expand All @@ -180,7 +253,7 @@ public Delegate CreateLambda(string sName, string sCode, Type typeDelegate, Type
{
using (LuaLexer l = new LuaLexer(sName, new StringReader(sCode)))
{
LambdaExpression expr = Parser.ParseChunk(this, LuaDebugLevel.None, false, l, typeDelegate, returnType, arguments);
LambdaExpression expr = Parser.ParseChunk(this, new LuaCompileOptions(), false, l, typeDelegate, returnType, arguments);

if (lPrintExpressionTree)
{
Expand Down Expand Up @@ -402,7 +475,7 @@ public string StandardPackagesPath
// -- Static --------------------------------------------------------------

private static object lockDefaultDebugEngine = new object();
private static ILuaDebug defaultDebugEngine = null;
private static LuaCompileOptions defaultDebugEngine = null;

private static int iRegisteredChunkLock = 0;
private static Dictionary<string, WeakReference> registeredChunks = new Dictionary<string, WeakReference>();
Expand Down Expand Up @@ -492,13 +565,13 @@ public static LuaChunk GetChunkFromMethodInfo(MethodBase mi)
#endregion

/// <summary>Returns a default StackTrace-Debug Engine</summary>
public static ILuaDebug DefaultDebugEngine
public static LuaCompileOptions DefaultDebugEngine
{
get
{
lock (lockDefaultDebugEngine)
if (defaultDebugEngine == null)
defaultDebugEngine = new LuaStackTraceDebugger();
defaultDebugEngine = new LuaCompileOptions() { DebugEngine = new LuaStackTraceDebugger() };
return defaultDebugEngine;
}
} // prop DefaultDebugEngine
Expand Down
4 changes: 4 additions & 0 deletions NeoLua/LuaDebug.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ public interface ILuaDebugInfo

#endregion

#region -- class LuaStackTraceDebugger ----------------------------------------------

///////////////////////////////////////////////////////////////////////////////
/// <summary>Debugger that creates the methods as dynamic assembly, with them
/// it is possible to retrieve exact stacktraces. This debugger is good if
Expand Down Expand Up @@ -464,4 +466,6 @@ private static AssemblyName GetLuaDynamicName()
}
} // func GetLuaDynamicName
} // class StackTraceDebugger

#endregion
}
Loading

0 comments on commit b74aca9

Please sign in to comment.