From 08b14e3af0384bf23de3fa976ae94e212819218e Mon Sep 17 00:00:00 2001
From: Jeija <norrepli@gmail.com>
Date: Sun, 13 Mar 2016 13:43:55 +0100
Subject: Luacontroller: Fix function usage in LuaJIT, make 'do' no longer
 prohibited, remove pcall and xpcall, fix global lookup of "jit" variable,
 correct error locations

Thanks to @ShadowNinja and @gamemanj for fixing this in #241
---
 mesecons_luacontroller/init.lua | 30 +++++++++++++++++++++++-------
 1 file changed, 23 insertions(+), 7 deletions(-)

diff --git a/mesecons_luacontroller/init.lua b/mesecons_luacontroller/init.lua
index 839d150..2aa4328 100644
--- a/mesecons_luacontroller/init.lua
+++ b/mesecons_luacontroller/init.lua
@@ -249,8 +249,8 @@ end
 
 
 local safe_globals = {
-	"assert", "error", "ipairs", "next", "pairs", "pcall", "select",
-	"tonumber", "tostring", "type", "unpack", "_VERSION", "xpcall",
+	"assert", "error", "ipairs", "next", "pairs", "select",
+	"tonumber", "tostring", "type", "unpack", "_VERSION"
 }
 local function create_environment(pos, mem, event)
 	-- Gather variables for the environment
@@ -340,17 +340,17 @@ end
 
 local function timeout()
 	debug.sethook()  -- Clear hook
-	error("Code timed out!")
+	error("Code timed out!", 2)
 end
 
 
 local function code_prohibited(code)
 	-- LuaJIT doesn't increment the instruction counter when running
 	-- loops, so we have to sanitize inputs if we're using LuaJIT.
-	if not jit then
+	if not rawget(_G, "jit") then
 		return false
 	end
-	local prohibited = {"while", "for", "do", "repeat", "until", "goto"}
+	local prohibited = {"while", "for", "repeat", "until", "goto"}
 	code = " "..code.." "
 	for _, p in ipairs(prohibited) do
 		if string.find(code, "[^%w_]"..p.."[^%w_]") then
@@ -369,10 +369,26 @@ local function create_sandbox(code, env)
 	setfenv(f, env)
 
 	return function(...)
-		debug.sethook(timeout, "", 10000)
+		-- Normal Lua: Use instruction counter to stop execution
+		-- after luacontroller_maxevents.
+		-- LuaJIT: Count function calls instead of instructions, allows usage
+		-- of function keyword. However, LuaJIT still doesn't trigger
+		-- lines events when using infinite loops.
+		local maxevents = mesecon.setting("luacontroller_maxevents", 10000)
+		if not rawget(_G, "jit") then
+			debug.sethook(timeout, "", maxevents)
+		else
+			local events = 0
+			debug.sethook(function ()
+				events = events + 1
+				if events > maxevents then
+					timeout()
+				end
+			end, "c")
+		end
 		local ok, ret = pcall(f, ...)
 		debug.sethook()  -- Clear hook
-		if not ok then error(ret) end
+		if not ok then error(ret, 0) end
 		return ret
 	end
 end
-- 
cgit v1.2.3