Skip to content
This repository has been archived by the owner on Aug 18, 2020. It is now read-only.

Commit

Permalink
Validate binds to prevent crashes with IronPython
Browse files Browse the repository at this point in the history
  • Loading branch information
ForLoveOfCats committed Mar 6, 2019
1 parent 66084d3 commit cc61cfb
Showing 1 changed file with 110 additions and 7 deletions.
117 changes: 110 additions & 7 deletions Scripting/Bindings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ public enum BIND_TYPE {SCANCODE, MOUSEBUTTON, MOUSEWHEEL, AXIS}
private static string[] MouseWheelList = {"WheelUp", "WheelDown"};
private static string[] AxisList = {"MouseUp", "MouseDown", "MouseRight", "MouseLeft"};
private static List<BindingObject> BindingsWithArg = new List<BindingObject>();
private static List<BindingObject> BindingsWithoutArg = new List<BindingObject>();

private static Bindings Self;
private Bindings()
Expand All @@ -20,6 +21,46 @@ private Bindings()

public static void Bind(string FunctionName, string InputString)
{
dynamic Variable;
Scripting.ConsoleScope.TryGetVariable(FunctionName, out Variable);
if(Variable == null || !(Variable is Delegate || Variable is IronPython.Runtime.PythonFunction))
{
Console.ThrowPrint($"'{FunctionName}' is not a valid function");
return;
}

Nullable<int> ArgCount = null; //null for the sanity check
if(Variable is Delegate)
{
ArgCount = (Variable as Delegate).Method.GetParameters().Length;
}
else if(Variable is IronPython.Runtime.PythonFunction)
{
ArgCount = Scripting.ConsoleEngine.Execute($"len({FunctionName}.func_code.co_varnames)");
}

if(ArgCount == null)
{
//Sanity check
Console.ThrowPrint($"Cannot find argument count of '{FunctionName}', please contact the developers'");
return;
}

if(ArgCount != 0 && ArgCount != 1)
{
Console.ThrowPrint($"Function '{FunctionName}' must take either one or two arguments");
return;
}
if(ArgCount == 1 && Variable is Delegate)
{
//TODO Update this once we move to floats instead of doubles
if(!((Delegate)Variable).Method.GetParameters()[0].ParameterType.IsInstanceOfType(new double()))
{
Console.ThrowPrint($"Builtin command '{FunctionName}' has a single non-double argument");
return;
}
}

BIND_TYPE Type = BIND_TYPE.SCANCODE;
if(System.Array.IndexOf(MouseButtonList, InputString) >= 0)
{
Expand All @@ -41,7 +82,9 @@ public static void Bind(string FunctionName, string InputString)
{
if(Bind.Name == FunctionName)
{
//Does not throw exception when not found
BindingsWithArg.Remove(Bind);
BindingsWithoutArg.Remove(Bind);
break;
}
}
Expand All @@ -53,7 +96,19 @@ public static void Bind(string FunctionName, string InputString)
InputEventKey Event = new InputEventKey();
Event.Scancode = OS.FindScancodeFromString(InputString);
InputMap.ActionAddEvent(FunctionName, Event);
BindingsWithArg.Add(new BindingObject(FunctionName, Type));

if(ArgCount == 1)
{
BindingsWithArg.Add(new BindingObject(FunctionName, Type));
}
else if(ArgCount == 0)
{
BindingsWithoutArg.Add(new BindingObject(FunctionName, Type));
}
else
{
Console.ThrowPrint($"Cannot add SCANCODE bind, '{FunctionName}' has an unsuported number of arguments");
}
}
else if(Type == BIND_TYPE.MOUSEBUTTON)
{
Expand All @@ -73,7 +128,19 @@ public static void Bind(string FunctionName, string InputString)
//No default as this else if will not run unless one of these string will match anyway
}
InputMap.ActionAddEvent(FunctionName, Event);
BindingsWithArg.Add(new BindingObject(FunctionName, Type));

if(ArgCount == 1)
{
BindingsWithArg.Add(new BindingObject(FunctionName, Type));
}
else if(ArgCount == 0)
{
BindingsWithoutArg.Add(new BindingObject(FunctionName, Type));
}
else
{
Console.ThrowPrint($"Cannot add MOUSEBUTTON bind, '{FunctionName}' has an unsuported number of arguments");
}
}
else if(Type == BIND_TYPE.MOUSEWHEEL)
{
Expand All @@ -89,7 +156,19 @@ public static void Bind(string FunctionName, string InputString)
break;
}
InputMap.ActionAddEvent(FunctionName, Event);
BindingsWithArg.Add(new BindingObject(FunctionName, Type));

if(ArgCount == 1)
{
BindingsWithArg.Add(new BindingObject(FunctionName, Type));
}
else if(ArgCount == 0)
{
BindingsWithoutArg.Add(new BindingObject(FunctionName, Type));
}
else
{
Console.ThrowPrint($"Cannot add MOUSEWHEEL bind, '{FunctionName}' has an unsuported number of arguments");
}
}
else if(Type == BIND_TYPE.AXIS)
{
Expand Down Expand Up @@ -126,7 +205,9 @@ public static void UnBind(string FunctionName)
{
if(Bind.Name == FunctionName)
{
//Does not throw exception when not found
BindingsWithArg.Remove(Bind);
BindingsWithoutArg.Remove(Bind);
break;
}
}
Expand Down Expand Up @@ -172,6 +253,24 @@ public override void _Process(float Delta)
}
}
}

foreach(BindingObject Binding in BindingsWithoutArg)
{
if(Binding.Type == BIND_TYPE.SCANCODE || Binding.Type == BIND_TYPE.MOUSEBUTTON)
{
if(Input.IsActionJustPressed(Binding.Name))
{
Scripting.ConsoleEngine.Execute($"{Binding.Name}()", Scripting.ConsoleScope);
}
}
else if(Binding.Type == BIND_TYPE.MOUSEWHEEL)
{
if(Input.IsActionJustReleased(Binding.Name))
{
Scripting.ConsoleEngine.Execute($"{Binding.Name}()", Scripting.ConsoleScope);
}
}
}
}


Expand All @@ -192,23 +291,27 @@ public override void _Input(InputEvent Event)
{
case(BindingObject.DIRECTION.UP):
Scripting.ConsoleEngine.Execute($"{Binding.Name}({(double)new decimal (GreaterEqualZero(MotionEvent.Relative.y*-1))})", Scripting.ConsoleScope);
// Scripting.ConsoleEngine.CallGlobalFunction(Binding.Name, (double)new decimal (GreaterEqualZero(MotionEvent.Relative.y*-1)));
break;
case(BindingObject.DIRECTION.DOWN):
Scripting.ConsoleEngine.Execute($"{Binding.Name}({(double)new decimal (GreaterEqualZero(MotionEvent.Relative.y))})", Scripting.ConsoleScope);
// Scripting.ConsoleEngine.CallGlobalFunction(Binding.Name, (double)new decimal (GreaterEqualZero(MotionEvent.Relative.y)));
break;
case(BindingObject.DIRECTION.RIGHT):
Scripting.ConsoleEngine.Execute($"{Binding.Name}({(double)new decimal (GreaterEqualZero(MotionEvent.Relative.x))})", Scripting.ConsoleScope);
// Scripting.ConsoleEngine.CallGlobalFunction(Binding.Name, (double)new decimal (GreaterEqualZero(MotionEvent.Relative.x)));
break;
case(BindingObject.DIRECTION.LEFT):
Scripting.ConsoleEngine.Execute($"{Binding.Name}({(double)new decimal (GreaterEqualZero(MotionEvent.Relative.x*-1))})", Scripting.ConsoleScope);
// Scripting.ConsoleEngine.CallGlobalFunction(Binding.Name, (double)new decimal (GreaterEqualZero(MotionEvent.Relative.x*-1)));
break;
}
}
}

foreach(BindingObject Binding in BindingsWithoutArg)
{
if(Binding.Type == BIND_TYPE.AXIS)
{
Scripting.ConsoleEngine.Execute($"{Binding.Name}()", Scripting.ConsoleScope);
}
}
}
}
}

0 comments on commit cc61cfb

Please sign in to comment.