TPT: Prevent accidental infinite loops in lua, fixes #115
This commit is contained in:
parent
51a0fb2d45
commit
72e441132f
@ -30,6 +30,7 @@ int tptPropertiesVersion;
|
|||||||
int tptElements; //Table for TPT element names
|
int tptElements; //Table for TPT element names
|
||||||
int tptParts, tptPartsMeta, tptElementTransitions, tptPartsCData, tptPartMeta, tptPart, cIndex;
|
int tptParts, tptPartsMeta, tptElementTransitions, tptPartsCData, tptPartMeta, tptPart, cIndex;
|
||||||
|
|
||||||
|
void luacon_hook(lua_State *L, lua_Debug *ar);
|
||||||
int luacon_step(int mx, int my, int selectl, int selectr, int bsx, int bsy);
|
int luacon_step(int mx, int my, int selectl, int selectr, int bsx, int bsy);
|
||||||
int luacon_mouseevent(int mx, int my, int mb, int event, int mouse_wheel);
|
int luacon_mouseevent(int mx, int my, int mb, int event, int mouse_wheel);
|
||||||
int luacon_keyevent(int key, int modifier, int event);
|
int luacon_keyevent(int key, int modifier, int event);
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#else
|
#else
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
LuaScriptInterface::LuaScriptInterface(GameModel * m):
|
LuaScriptInterface::LuaScriptInterface(GameModel * m):
|
||||||
CommandInterface(m),
|
CommandInterface(m),
|
||||||
@ -141,6 +142,7 @@ LuaScriptInterface::LuaScriptInterface(GameModel * m):
|
|||||||
lua_setfield(l, tptPropertiesVersion, "build");
|
lua_setfield(l, tptPropertiesVersion, "build");
|
||||||
lua_setfield(l, tptProperties, "version");
|
lua_setfield(l, tptProperties, "version");
|
||||||
|
|
||||||
|
lua_sethook(l, &luacon_hook, LUA_MASKCOUNT, 200);
|
||||||
#ifdef FFI
|
#ifdef FFI
|
||||||
//LuaJIT's ffi gives us direct access to parts data, no need for nested metatables. HOWEVER, this is in no way safe, it's entirely possible for someone to try to read parts[-10]
|
//LuaJIT's ffi gives us direct access to parts data, no need for nested metatables. HOWEVER, this is in no way safe, it's entirely possible for someone to try to read parts[-10]
|
||||||
lua_pushlightuserdata(l, parts);
|
lua_pushlightuserdata(l, parts);
|
||||||
@ -300,6 +302,7 @@ bool LuaScriptInterface::OnKeyRelease(int key, Uint16 character, bool shift, boo
|
|||||||
|
|
||||||
void LuaScriptInterface::OnTick()
|
void LuaScriptInterface::OnTick()
|
||||||
{
|
{
|
||||||
|
LoopTime = clock();
|
||||||
if(luacon_mousedown)
|
if(luacon_mousedown)
|
||||||
luacon_mouseevent(luacon_mousex, luacon_mousey, luacon_mousebutton, LUACON_MPRESS, 0);
|
luacon_mouseevent(luacon_mousex, luacon_mousey, luacon_mousebutton, LUACON_MPRESS, 0);
|
||||||
luacon_step(luacon_mousex, luacon_mousey, luacon_selectedl, luacon_selectedr, luacon_brushx, luacon_brushy);
|
luacon_step(luacon_mousex, luacon_mousey, luacon_selectedl, luacon_selectedr, luacon_brushx, luacon_brushy);
|
||||||
@ -319,6 +322,7 @@ int LuaScriptInterface::Command(std::string command)
|
|||||||
int ret;
|
int ret;
|
||||||
lastError = "";
|
lastError = "";
|
||||||
currentCommand = true;
|
currentCommand = true;
|
||||||
|
LoopTime = clock();
|
||||||
if((ret = luaL_dostring(l, command.c_str())))
|
if((ret = luaL_dostring(l, command.c_str())))
|
||||||
{
|
{
|
||||||
lastError = luacon_geterror();
|
lastError = luacon_geterror();
|
||||||
@ -874,28 +878,42 @@ int luacon_step(int mx, int my, int selectl, int selectr, int bsx, int bsy){
|
|||||||
lua_setfield(luacon_ci->l, tptProperties, "selectedr");
|
lua_setfield(luacon_ci->l, tptProperties, "selectedr");
|
||||||
lua_setfield(luacon_ci->l, tptProperties, "brushx");
|
lua_setfield(luacon_ci->l, tptProperties, "brushx");
|
||||||
lua_setfield(luacon_ci->l, tptProperties, "brushy");
|
lua_setfield(luacon_ci->l, tptProperties, "brushy");
|
||||||
if(step_functions[0]){
|
for(i = 0; i<6; i++){
|
||||||
//Set mouse globals
|
if(step_functions[i]){
|
||||||
for(i = 0; i<6; i++){
|
lua_rawgeti(luacon_ci->l, LUA_REGISTRYINDEX, step_functions[i]);
|
||||||
if(step_functions[i]){
|
callret = lua_pcall(luacon_ci->l, 0, 0, 0);
|
||||||
lua_rawgeti(luacon_ci->l, LUA_REGISTRYINDEX, step_functions[i]);
|
if (callret)
|
||||||
callret = lua_pcall(luacon_ci->l, 0, 0, 0);
|
{
|
||||||
if (callret)
|
if (!strcmp(luacon_geterror(),"Error: Script not responding"))
|
||||||
{
|
{
|
||||||
luacon_ci->Log(CommandInterface::LogError, luacon_geterror());
|
luacon_ci->LoopTime = clock();
|
||||||
|
lua_pushcfunction(luacon_ci->l, &luatpt_unregister_step);
|
||||||
|
lua_rawgeti(luacon_ci->l, LUA_REGISTRYINDEX, step_functions[i]);
|
||||||
|
lua_pcall(luacon_ci->l, 1, 0, 0);
|
||||||
}
|
}
|
||||||
|
luacon_ci->Log(CommandInterface::LogError, luacon_geterror());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return tempret;
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int luacon_eval(char *command){
|
int luacon_eval(char *command){
|
||||||
|
luacon_ci->LoopTime = clock();
|
||||||
return luaL_dostring (luacon_ci->l, command);
|
return luaL_dostring (luacon_ci->l, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void luacon_hook(lua_State * l, lua_Debug * ar)
|
||||||
|
{
|
||||||
|
if(ar->event == LUA_HOOKCOUNT && clock()-luacon_ci->LoopTime > CLOCKS_PER_SEC*3)
|
||||||
|
{
|
||||||
|
if(ConfirmPrompt::Blocking("Script not responding", "The Lua script may have stopped responding. There might be an infinite loop. Press \"Stop\" to stop it", "Stop"))
|
||||||
|
luaL_error(l, "Error: Script not responding");
|
||||||
|
luacon_ci->LoopTime = clock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
char *luacon_geterror(){
|
char *luacon_geterror(){
|
||||||
char *error = (char*)lua_tostring(luacon_ci->l, -1);
|
char *error = (char*)lua_tostring(luacon_ci->l, -1);
|
||||||
if(error==NULL || !error[0]){
|
if(error==NULL || !error[0]){
|
||||||
|
@ -40,6 +40,7 @@ class LuaScriptInterface: public CommandInterface {
|
|||||||
bool currentCommand;
|
bool currentCommand;
|
||||||
TPTScriptInterface * legacy;
|
TPTScriptInterface * legacy;
|
||||||
public:
|
public:
|
||||||
|
int LoopTime;
|
||||||
lua_State *l;
|
lua_State *l;
|
||||||
LuaScriptInterface(GameModel * m);
|
LuaScriptInterface(GameModel * m);
|
||||||
virtual bool OnBrushChanged(int brushType, int rx, int ry);
|
virtual bool OnBrushChanged(int brushType, int rx, int ry);
|
||||||
|
Loading…
Reference in New Issue
Block a user