我正在尝试使用Janino构建脚本沙箱,这样我就可以通过限制导入,CPU时间和分配的字节来安全地执行用户函数。
在Rhino中(对于javascript代码)我有一个名为 observeInstructionCount(Context ctx,int instructionCount)的函数,每个 X 指令调用 X < / strong>可以在构建环境时由用户定义。
在这个函数中,我可以这样做:
/**
* This method is called every {@code instructionsBeforeObserve} and it is
* used to check if the current execution has exceded the {@code maxCpuTime}
* or the {maxMemory}. If so, an {@link java.lang.Error} is thrown.
*
*/
@Override
protected void observeInstructionCount(Context cx, int instructionCount) {
SafeContext sctx = (SafeContext) cx;
//Check CPU Time
if (getMaxCpuTime() > 0) {
long currentTime = System.currentTimeMillis();
if (currentTime - sctx.getStartTime() > getMaxCpuTime()) {
throw new Error("Max CPU Time limit of " + getMaxCpuTime() + " was exceeded");
}
}
//Check Memory Consumption
if (getMaxMemory() > 0 && threadMonitor != null) {
if (sctx.getStartMemory() <= 0) {
sctx.setStartMemory(threadMonitor.getThreadAllocatedBytes(sctx.getThreadId()));
} else {
long currentAllocatedBytes = threadMonitor.getThreadAllocatedBytes(sctx.getThreadId());
if ((currentAllocatedBytes - sctx.getStartMemory()) >= getMaxMemory()) {
throw new Error("Max Memory limit of " + getMaxMemory() + " was exceeded");
}
}
}
}
监视执行时间和分配的字节。
即使用户创建了一个循环(例如while(true){}),最终也会调用此函数,如果超出了过去定义的执行时间,则会抛出错误并且脚本执行将停止。
我正在尝试使用Janino复制此行为,但我没有类似的机制来监视脚本执行。如果用户调用阻塞函数,我无法停止脚本,然后在执行脚本的线程上突然调用thread.stop(),这可能会有问题。任何其他调用如thread.interrupt()(据我所知)都不会中断阻塞调用。
关于如何解决这个问题的任何想法?