2010-08-03 2 views
9
luaL_loadfile(mState, path.c_str()); 
lua_pcall(mState, 0, 0, 0); 

두 개의 C++ 문에 대해 실행 시간 제한 (예 : 10-20 초)을 넣고 루아 파일을로드 한 다음 실행하는 방법이 있습니까?C API에서 호출되는 루아 스크립트의 실행 시간 제한

Lua 파일은 신뢰할 수 없으므로 악의적 인 사용자가 루아 코드에서 무한 루프로 프로그램을 무한정 중단 시키길 원치 않습니다. 루아 API는 C 태그 C가있다

태그 C 때문에 ++ 나 C++

답변

20

모든 후 훅을 호출하는 인터프리터에게 사용할 수있는 lua_sethook있다을 사용하고 있기 때문에 실행 지침을 '계산'. 이 방법 당신은 사용자 스크립트를 모니터링하고 할당량까지 먹는 경우를 종료 할 수 있습니다 :

int lua_sethook (lua_State *L, lua_Hook f, int mask, int count); 

이것은 또한 루아에서 사용할 수있다 :

debug.sethook(function() print("That's enough for today"); os.exit(0); end, "", 10000) 
for i=1,10000 do end 

당신이 다음 http://lua-users.org/wiki/SandBoxes에서 기술을 사용하는 경우 당신이 할 수있는 sethook() 및 친구들과 Lua의 안전한 실행 환경을 설정 한 다음 사용자 스크립트를 실행하는 동안 샌드 박스 모드로 전환하십시오. 나는 여기에서 당신이 시작하려고 노력했다.

-- set an execution quota 
local function set_quota(secs) 
local st=os.clock() 
function check() 
    if os.clock()-st > secs then 
    debug.sethook() -- disable hooks 
    error("quota exceeded") 
    end 
end 
debug.sethook(check,"",100000); 
end 

-- these are the global objects, the user can use: 
local env = {print=print} 

-- The user code is allowed to run for 5 seconds. 
set_quota(5) 

-- run code under environment: 
local function run(untrusted_code) 
    local untrusted_function, message = loadstring(untrusted_code) 
    if not untrusted_function then return nil, message end 
    setfenv(untrusted_function, env) 
    return pcall(untrusted_function) 
end 

-- here is the user code: 
local userscript=[[ 
function fib(n) 
if n<2 then return n 
else return fib(n-2)+fib(n-1) 
end 
end 
for n=1,42 do print(n,fib(n)) end 
]] 
-- call it: 
local r,m=run(userscript) 
print(r,m) 

이것은 fib() 값을 5 초 동안 인쇄 한 다음 오류를 표시해야한다.

+0

위대한 답변, 감사합니다! –