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

Có cách nào để đặt giới hạn thời gian thực thi (giả sử 10-20 giây) cho hai câu lệnh C++ đó không và sau đó thực thi tệp lua?Giới hạn thời gian thực thi cho một kịch bản Lua được gọi từ C API

Vì tệp Lua không đáng tin cậy nên tôi không muốn người dùng độc hại treo chương trình vô thời hạn bằng vòng lặp vô hạn trong mã Lua.

Tagging C vì API Lua là C, gắn thẻ C++ vì tôi đang sử dụng C++

Trả lời

20

Có lua_sethook mà có thể được sử dụng để nói với người phiên dịch để gọi một cái móc sau mỗi lần 'đếm' hướng dẫn thực hiện. Bằng cách này bạn có thể giám sát kịch bản sử dụng và chấm dứt nó nếu nó ăn lên hạn ngạch:

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

này cũng có thể được sử dụng từ Lua:

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

Nếu bạn sử dụng các kỹ thuật từ http://lua-users.org/wiki/SandBoxes sau đó bạn có thể thiết lập môi trường thực thi an toàn với sethook() và bạn bè hoàn toàn từ Lua và sau đó chuyển sang chế độ hộp cát trong khi thực thi tập lệnh người dùng. Tôi đã thử ở đây, chỉ để bạn bắt đầu:

-- 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) 

Điều này sẽ in giá trị fib() trong 5 giây và sau đó hiển thị lỗi.

+0

Câu trả lời hay, cảm ơn bạn! –

Các vấn đề liên quan