Closed pygy closed 10 years ago
I just realized that you were providing loadstring
, which makes it possible to completely implement require from the application.
It makes me wonder why you restrict moai.code.loadsource(filename)
to files uploaded through the zip file , though...
Rob - wanted to make sure you didn't miss this one.
I'll take a look at this since I would like to allow people to choose what they want to include instead of having every thing available by default in the sandbox (although there are performance gains from just loading everything once at the start). Additionally I'd like to allow users the ability to reference and load code from other services they own so they can create libraries that they share across services.
From a security and performance stand point, I think it would make sense to provide two isolated filesystem roots per service, with different functions for doing io.
require
, loadfile
and dofile
work as expected.file.*
operations work as expected.This would allow to cache the code partition on each application server, and would prevent a range of arbitrary code execution vulnerabilities.
Is loadstring
a most wanted feature? Would it still be if you implemented the above suggestion?
One thing we want to provide is a shared data space across services owned by a user. It's easy enough to swap the above per-service data space you mention with one that is instead service wide. We could also provide three if users want it.
Also for the R/W spaces is re-implementing the file.* operations on top of mongo desirable or is sticking with the mongo gridfs api sufficient?
You're right about io.* (and not file.* as I wrote earlier) it makes little sense to provide them when Mongo can store structured data. Also, incremental writes would be very inefficient.
I completely overlooked the issue of environments (require
loads libraries in _G). Here's require
, with that concern in mind. It is based on PiL2 and the Lua source. I'm in the process of writing module
.
sandbox.package={loaded={}}
local _loaded, _loaders
= sandbox.package.loaded, package.loaders
local _sentinel = {}
function sandbox.require (name)
if _loaded[name] == _sentinel then
error("loop or previous error loading module "..name)
end
if not _loaded[name] then -- module not loaded yet?
_loaded[name] = _sentinel
local trace, loader = ""
for _,l in ipairs(_loaders) do
-- limited to package.preload and local source files on local fs.
res = l(name)
id type(res) == "function" then loader=res; break end
if type(res) == string then trace = trace..res end
end
if loader == nil then
error("unable to load module " .. name .. trace)
end
local res = loader(name)
if res ~= nil
then _loaded[name] = res
else _loaded[name] = true
end
end
return _loaded[name]
end
Wasn't module removed in lua 5.2? I"ll review this and try to get it in shortly. Another feature I'd like to expose it to allow users to do things like:
require 'moai:/
So instead of having to bundle the same code in two different services they can create and load libraries.
Yes, it was removed, but a lot of 5.1 libraries use it. You already use 5.2 in the cloud?
For the preloaded libs, you could populate the package.preload
table. The first loader (searcher in 5.2 nomenclature) looks there for packages. You get the best of both world: the libs are preloaded, but only run when required, and it doesn't pollute the global environment.
MOAI Cloud ended. Close.
Require is very convenient.
The following code implements a secure require() functionality for theMoai cloud. Actually, you expose the real require function in the sandbox, but only provide a single, secure loader.
require
iterates through thepackage.loaders
table for a loader suitable for the string it was passed. You can replace the standard loaders with your own.The 'dot notation' is supported. The root directory, 'lib' and 'Library' are added to the standard path by default, but the user can add more if he wants to.
require'mod.submodule'
will search the path formod/submodule.lua
andmod/submodule/init.lua
. C libraries are not supported.A similar loader could allow you to host modules for your users with more granularity than the current solution where you add everything in the global table by default.
This is adapted from code I wrote for a LÖVE library.