sandbox.lua
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:4k
源码类别:

midi

开发平台:

Unix_Linux

  1. --[==========================================================================[
  2.  sandbox.lua: Lua sandboxing facilities
  3. --[==========================================================================[
  4.  Copyright (C) 2007 the VideoLAN team
  5.  $Id$
  6.  Authors: Antoine Cellerier <dionoea at videolan dot org>
  7.  This program is free software; you can redistribute it and/or modify
  8.  it under the terms of the GNU General Public License as published by
  9.  the Free Software Foundation; either version 2 of the License, or
  10.  (at your option) any later version.
  11.  This program is distributed in the hope that it will be useful,
  12.  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  GNU General Public License for more details.
  15.  You should have received a copy of the GNU General Public License
  16.  along with this program; if not, write to the Free Software
  17.  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  18. --]==========================================================================]
  19. module("sandbox",package.seeall)
  20. -- See Programming in Lua (second edition) for sandbox examples
  21. -- See http://lua-users.org/wiki/SandBoxes for a list of SAFE/UNSAFE variables
  22. local sandbox_blacklist = {
  23.     collectgarbage = true,
  24.     dofile = true,
  25.     _G = true,
  26.     getfenv = true,
  27.     getmetatable = true,
  28.     load = true, -- Can be protected I guess
  29.     loadfile = true, -- Can be protected I guess
  30.     loadstring = true, -- Can be protected I guess
  31.     rawequal = true,
  32.     rawget = true,
  33.     rawset = true,
  34.     setfenv = true,
  35.     setmetatable = true,
  36.     module = true,
  37.     require = true,
  38.     package = true,
  39.     debug = true,
  40. }
  41. function readonly_table_proxy(name,src,blacklist)
  42.     if type(src)=="nil" then return end
  43.     if type(src)~="table" then error("2nd argument must be a table (or nil)") end
  44.     local name = name
  45.     local t = src
  46.     local blist = {}
  47.     if blacklist then
  48.         for _, v in pairs(blacklist) do
  49.             blist[v] = true
  50.         end
  51.     end
  52.     local metatable_readonly = {
  53.         __index = function(self,key)
  54.             if blist[key] then
  55.                 error("Sandbox: Access to `"..name.."."..key.."' is forbidden.")
  56.             end
  57.             return t[key]
  58.         end,
  59.         __newindex = function(self,key,value)
  60.             error("It is forbidden to modify elements of this table.")
  61.         end,
  62.     }
  63.     return setmetatable({},metatable_readonly)
  64. end
  65. -- Of course, all of this is useless if the sandbox calling code has
  66. -- another reference to one of these tables in his global environement.
  67. local sandbox_proxy = {
  68.     coroutine   = readonly_table_proxy("coroutine",coroutine),
  69.     string      = readonly_table_proxy("string",string,{"dump"}),
  70.     table       = readonly_table_proxy("table",table),
  71.     math        = readonly_table_proxy("math",math),
  72.     io          = readonly_table_proxy("io",io),
  73.     os          = readonly_table_proxy("os",os,{"exit","getenv","remove",
  74.                                                 "rename","setlocale"}),
  75.     sandbox     = readonly_table_proxy("sandbox",sandbox),
  76. }
  77. function sandbox(func,override)
  78.     local _G = getfenv(2)
  79.     local override = override or {}
  80.     local sandbox_metatable =
  81.     {
  82.         __index = function(self,key)
  83.             if override[key] then
  84.                 return override[key]
  85.             end
  86.             if sandbox_blacklist[key] then
  87.                 error( "Sandbox: Access to `"..key.."' is forbidden." )
  88.             end
  89.             --print(key,"not found in env. Looking in sandbox_proxy and _G")
  90.             local value = sandbox_proxy[key] or _G[key]
  91.             rawset(self,key,value) -- Keep a local copy
  92.             return value
  93.         end,
  94.         __newindex = function(self,key,value)
  95.             if override and override[key] then
  96.                 error( "Sandbox: Variable `"..key.."' is read only." )
  97.             end
  98.             return rawset(self,key,value)
  99.         end,
  100.     }
  101.     local sandbox_env = setmetatable({},sandbox_metatable)
  102.     return function(...)
  103.         setfenv(func,sandbox_env)
  104.         local ret = {func(...)} -- Not perfect (if func returns nil before
  105.                                 -- another return value) ... but it's better
  106.                                 -- than nothing
  107.         setfenv(func,_G)
  108.         return unpack(ret)
  109.     end
  110. end