以下概念验证演示了基本级别的沙盒和任意用户代码的节流。它成功地运行了约250条指令的“用户输入”,然后丢弃了协同程序。不幸的是,Java进程永远不会终止。稍微调查一下发现,LuaJ为协同程序创建的LuaThread一直挂着。
SandboxTest.java:
public static void main(String[] args) {
Globals globals = JsePlatform.debugGlobals();
LuaValue chunk = globals.loadfile("res/test.lua");
chunk.call();
}
res/test.lua:
function sandbox(fn)
-- read script and set the environment
f = loadfile(fn, "t")
debug.setupvalue(f, 1, {print = print})
-- create a coroutine and have it yield every 50 instructions
local co = coroutine.create(f)
debug.sethook(co, coroutine.yield, "", 50)
-- demonstrate stepped execution, 5 'ticks'
for i = 1, 5 do
print("tick")
coroutine.resume(co)
end
end
sandbox("res/badfile.lua")
res/badfile.lua:
while 1 do
print("", "badfile")
end
文档建议,如果一个协程被认为是无法恢复的,它将被垃圾回收并抛出
OrphanedThread
异常,信号LuaThread
结束 - 但这从未发生过。我的问题分为两个部分:
- 我是否做了一些根本错误导致了这种行为?
- 如果没有,我应该如何处理这种情况?从源代码中看,如果我能在Java中获取对
LuaThread
的引用,我可以通过发出interrupt()
来强制放弃它。这是个好主意吗?
参考:Lua / Java / LuaJ - 处理或中断无限循环和线程
编辑:我在LuaJ SourceForge发布了一个漏洞报告。它讨论了潜在的问题(线程未像Lua规范中那样被垃圾回收)并提出了一些解决方法。