<span id="_ctl0_PostForm_PreviewBody">I have just found Squirrel and it
seems like a great language. It is lightweight like Lua and has C-like
syntax which I like better.
I'm seriously considering using Squrrel instead of Lua, but I wouder if
the following is possible. Let's suppose we have a game engine which
uses scripting for configuration purposes. It loads and executes
scripts which can specify some settings, register user made callbacks
and allow to extend the game. Naturally as such scripts work as
plugins, can be created by third party persons and distributed
independently, scriptable plugins can be used by malicious people to
harm the users - for example delete some important files. So we need to
add some restrictions. On the other hand, some code written in a
scripting language can be a part of the engine and can provide some
supplementary functions, validate data and do other things. For maximum
flexibility, a scripts which are a part of the engine should be
unrestricted as they can be trusted.
In the following example (written in Lua), 'selected_fruits' is a table
of options which is read by C++ engine, all the validation is performed
by Lua functions which are part of the engine and ensure that values in
'selected_fruits' table are valid not matter what configuration scripts
are loaded. 'untrusted_script' is some Lua code which is loaded from
external files, it can contain just anything from correct configuration
to the code harmful for the system. Restriction for file API is not
enough, for example user scripts can intentially or unintentiallt
damage 'selected_fruits' table by adding invalid values to it, removing
values which they did not add there, etc.
Could you please help to make Sqirrel replacement for this example? I
did not find anything in Squirrel manual yet. Or probably tell me which
parts of the manual I should start reading.
-- part of game engine written in a scripted language
local valid_fruits = {
["apple"] = true,
["orange"] = true,
["pear"] = true,
["banana"] = true,
}
selected_fruits = {}
-- the only API function available to 'untrusted' scripts
function add_fruit(fruit)
if not valid_fruits[fruit] then return end
selected_fruits[fruit] = true
end
-- function using which 'untrusted' scripts are executed
function sandbox_call(untrusted_code)
local restricted_sandbox = { add_fruit = add_fruit }
restricted_sandbox = setmetatable({}, {
__index = restricted_sandbox,
__newindex = function(table, key, value)
error("Sandbox violation: attempt to modify global variable")
end
})
setfenv(untrusted_code, restricted_sandbox)
return pcall(untrusted_code)
end
-- come code probably loaded from external files, received from network, etc
-- it should selections a set of fruits from a predefined list, this list is
-- used by the main program as a configuration setting
function untrusted_script()
add_fruit("apple")
add_fruit("badfruit")
add_fruit("pear")
-- try to do something weird ()
os.remove("c:\\autoexec.bat")
end
local result, errmsg = sandbox_call(untrusted_script)
if errmsg then print("Error detected:") print(errmsg) end
print("List of selected fruits:")
for fruit in selected_fruits do print(fruit) end
</span>------------------------------------------------------------------------------------
It produces the following:
Error detected:
1.lua:38: attempt to index global `os' (a nil value)
List of selected fruits:
apple
pear