mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Scribunto
synced 2024-11-23 15:56:55 +00:00
Do not allow access to setfenv() and getfenv() by default
Optionally remove setfenv and getfenv from the global environment in which user code runs. This will improve the forwards-compatibility of user code with Lua 5.2. Porting to Lua 5.2 would still be a daunting project, of questionable value, but at least only the internal code would need updating, and not thousands of on-wiki modules. Compared to the environment changes, the rest of the Lua 5.2 changes are relatively easy to simulate for backwards compatibility. Removed module() from the package module, since it depends on setfenv(). The native version of it is deprecated in Lua 5.2 for that reason. Change-Id: I978903ca98943ac941833da13fe5027949f6b429
This commit is contained in:
parent
886c6ae06d
commit
441943bd9b
|
@ -92,6 +92,13 @@ $wgScribuntoEngineConf = array(
|
|||
'class' => 'Scribunto_LuaSandboxEngine',
|
||||
'memoryLimit' => 50 * 1024 * 1024,
|
||||
'cpuLimit' => 7,
|
||||
|
||||
// Set this to true to allow setfenv() and getfenv() in user code.
|
||||
// Note that these functions have been removed in Lua 5.2. Scribunto
|
||||
// does not yet support Lua 5.2, but we expect support will be
|
||||
// implemented in the future, and there is no guarantee that a
|
||||
// simulation of setfenv() and getfenv() will be provided.
|
||||
'allowEnvFuncs' => false,
|
||||
),
|
||||
'luastandalone' => array(
|
||||
'class' => 'Scribunto_LuaStandaloneEngine',
|
||||
|
@ -105,6 +112,7 @@ $wgScribuntoEngineConf = array(
|
|||
'luaPath' => null,
|
||||
'memoryLimit' => 50 * 1024 * 1024,
|
||||
'cpuLimit' => 7,
|
||||
'allowEnvFuncs' => false,
|
||||
),
|
||||
);
|
||||
|
||||
|
|
|
@ -52,7 +52,8 @@ abstract class Scribunto_LuaEngine extends ScribuntoEngineBase {
|
|||
'preprocess' => array( $this, 'preprocess' ),
|
||||
) );
|
||||
|
||||
$this->interpreter->callFunction( $this->mw['setup'] );
|
||||
$this->interpreter->callFunction( $this->mw['setup'],
|
||||
array( 'allowEnvFuncs' => $this->options['allowEnvFuncs'] ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -4,6 +4,7 @@ local packageCache
|
|||
local packageModuleFunc
|
||||
local php
|
||||
local setupDone
|
||||
local allowEnvFuncs = false
|
||||
|
||||
--- Put an isolation-friendly package module into the specified environment
|
||||
-- table. The package module will have an empty cache, because caching of
|
||||
|
@ -39,7 +40,7 @@ end
|
|||
|
||||
--- Set up the base environment. The PHP host calls this function after any
|
||||
-- necessary host-side initialisation has been done.
|
||||
function mw.setup()
|
||||
function mw.setup( options )
|
||||
if setupDone then
|
||||
return
|
||||
end
|
||||
|
@ -56,6 +57,10 @@ function mw.setup()
|
|||
end
|
||||
end
|
||||
|
||||
if options.allowEnvFuncs then
|
||||
allowEnvFuncs = true
|
||||
end
|
||||
|
||||
-- Make mw_php private
|
||||
--
|
||||
-- mw_php.loadPackage() returns function values with their environment
|
||||
|
@ -108,7 +113,14 @@ end
|
|||
function mw.executeModule( chunk )
|
||||
local env = mw.clone( _G )
|
||||
makePackageModule( env )
|
||||
env.setfenv, env.getfenv = mw.makeProtectedEnvFuncs( {[_G] = true}, {} )
|
||||
|
||||
if allowEnvFuncs then
|
||||
env.setfenv, env.getfenv = mw.makeProtectedEnvFuncs( {[_G] = true}, {} )
|
||||
else
|
||||
env.setfenv = nil
|
||||
env.getfenv = nil
|
||||
end
|
||||
|
||||
setfenv( chunk, env )
|
||||
return chunk()
|
||||
end
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
--]]
|
||||
|
||||
|
||||
local assert, error, getfenv, ipairs, pairs, setfenv, setmetatable, type = assert, error, getfenv, ipairs, pairs, setfenv, setmetatable, type
|
||||
local assert, error, ipairs, pairs, setmetatable, type = assert, error, ipairs, pairs, setmetatable, type
|
||||
local find, format, gfind, gsub, sub = string.find, string.format, string.gfind, string.gsub, string.sub
|
||||
|
||||
--
|
||||
|
@ -135,27 +135,3 @@ function _PACKAGE.seeall (module)
|
|||
end
|
||||
meta.__index = _G
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- module function
|
||||
--
|
||||
function _G.module (modname, ...)
|
||||
local ns = _LOADED[modname]
|
||||
if type(ns) ~= "table" then
|
||||
ns = findtable (_G, modname)
|
||||
if not ns then
|
||||
error (string.format ("name conflict for module '%s'", modname))
|
||||
end
|
||||
_LOADED[modname] = ns
|
||||
end
|
||||
if not ns._NAME then
|
||||
ns._NAME = modname
|
||||
ns._M = ns
|
||||
ns._PACKAGE = gsub (modname, "[^.]*$", "")
|
||||
end
|
||||
setfenv (2, ns)
|
||||
for i, f in ipairs (...) do
|
||||
f (ns)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,6 +7,7 @@ class Scribunto_LuaSandboxEngineTest extends Scribunto_LuaEngineTest {
|
|||
var $stdOpts = array(
|
||||
'memoryLimit' => 50000000,
|
||||
'cpuLimit' => 30,
|
||||
'allowEnvFuncs' => true,
|
||||
);
|
||||
|
||||
function newEngine( $opts = array() ) {
|
||||
|
|
|
@ -9,6 +9,7 @@ class Scribunto_LuaStandaloneEngineTest extends Scribunto_LuaEngineTest {
|
|||
'luaPath' => null,
|
||||
'memoryLimit' => 50000000,
|
||||
'cpuLimit' => 30,
|
||||
'allowEnvFuncs' => true,
|
||||
);
|
||||
|
||||
function newEngine( $opts = array() ) {
|
||||
|
|
Loading…
Reference in a new issue