我有一个python程序,用户应该能够在界面中编写自己的脚本。这里的语言应该是Lua。到目前为止,我有Lua沙箱,可以像这样一次执行用户代码:
lua_sandbox = lua.eval('''
function()
local function run(untrusted_code)
local untrusted_function, message = load(untrusted_code, nil, 't', _ENV)
if not untrusted_function then return nil, message end
return xpcall(untrusted_function, errorHandler)
end
-------------------- Defining Python functions and objects in Lua -------------------
local function PythonFunctionInLua(arg)
return python.eval('PythonFunction(' .. arg ..')')
end
PythonObjectInLua = python.eval('PythonObject')
-- Pass them to the local Lua sandbox
_ENV = { print = print,
PythonFunction = PythonFunctionInLua,
PythonObject = PythonObjectInLua,
coroutine = coroutine }
assert(run [[''' + code + ''' ]])
end
''')
到目前为止,这么好。现在我想添加逐步执行代码的可能性。到目前为止我最好的想法是使用调试钩子,所以我尝试了这个:
... (from above until _ENV)
debug.sethook(scripterDebug, "l")
func = assert( run [[''' + code + ''' ]] )
co = coroutine.create(func)
coroutine.resume(co)
出现问题:在用户再次点击处理下一行之前,我无法调用coroutine.yield
暂停例程。从外面拨打电话,例如在scripterDebug
钩子中,以及从内部调用它(将其插入code
部分)导致attempt to yield across C-Call boundary
t(我想我继续进出沙箱)在后一种情况下)。
我也尝试在run[[ ]]]
中创建协同程序,这是一个令人屈服的作品,但我不能在外面调用coroutine.resume(co)
,因为`co'只在沙箱中知道。我必须从外部调用它,因为当用户点击继续时调用它,如果我将访问权限等等传递到沙箱中,整个事情就变得毫无用处。
有没有办法在沙盒中逐步执行此代码?