Fix some obsolete names comments.

Change RHooks() interface to not require a 'rexec' instance argument;
added set_rexec() method instead (which must be called by the RExec
instance using this RHooks instance).

Support dynamic loading of modules, at least for those modules that
are ok built-in modules.  Added new interfaces set_trusted_path() and
load_dynamic() to RExec class (the default trusted path consists of
all absolute pathnames in sys.path).

Change copy_except() to actually try to delete the exceptions.
This commit is contained in:
Guido van Rossum 1996-05-28 23:07:17 +00:00
parent 9e6aa9d55b
commit fdd45cb858
1 changed files with 53 additions and 12 deletions

View File

@ -1,7 +1,7 @@
"""Restricted execution facilities.
The class RExec exports methods rexec(), reval(), rexecfile(), and
import_module(), which correspond roughly to the built-in operations
The class RExec exports methods r_exec(), r_eval(), r_execfile(), and
r_import(), which correspond roughly to the built-in operations
exec, eval(), execfile() and import, but executing the code in an
environment that only exposes those built-in operations that are
deemed safe. To this end, a modest collection of 'fake' modules is
@ -14,7 +14,6 @@
XXX To do:
- r_open should allow writing tmp dir
- r_exec etc. with explicit globals/locals? (Use rexec("exec ... in ...")?)
- r_reload should reload from same location (that's one for ihooks?)
"""
@ -61,10 +60,27 @@ def __init__(self, mod, name):
class RHooks(ihooks.Hooks):
def __init__(self, rexec, verbose=0):
def __init__(self, *args):
# Hacks to support both old and new interfaces:
# old interface was RHooks(rexec[, verbose])
# new interface is RHooks([verbose])
verbose = 0
rexec = None
if args and type(args[-1]) == type(0):
verbose = args[-1]
args = args[:-1]
if args and hasattr(args[0], '__class__'):
rexec = args[0]
args = args[1:]
if args:
raise TypeError, "too many arguments"
ihooks.Hooks.__init__(self, verbose)
self.rexec = rexec
def set_rexec(self, rexec):
# Called by RExec instance to complete initialization
self.rexec = rexec
def is_builtin(self, name):
return self.rexec.is_builtin(name)
@ -76,8 +92,8 @@ def init_frozen(self, name): raise SystemError, "don't use this"
def load_source(self, *args): raise SystemError, "don't use this"
def load_compiled(self, *args): raise SystemError, "don't use this"
def load_dynamic(self, *args):
raise ImportError, "import of dynamically loaded modules not allowed"
def load_dynamic(self, name, filename, file):
return self.rexec.load_dynamic(name, filename, file)
def add_module(self, name):
return self.rexec.add_module(name)
@ -130,11 +146,16 @@ class RExec(ihooks._Verbose):
def __init__(self, hooks = None, verbose = 0):
ihooks._Verbose.__init__(self, verbose)
# XXX There's a circular reference here:
self.hooks = hooks or RHooks(self, verbose)
self.hooks = hooks or RHooks(verbose)
self.hooks.set_rexec(self)
self.modules = {}
self.ok_builtin_modules = map(None, filter(
lambda mname: mname in sys.builtin_module_names,
self.ok_builtin_modules))
self.ok_dynamic_modules = self.ok_builtin_modules
list = []
for mname in self.ok_builtin_modules:
if mname in sys.builtin_module_names:
list.append(mname)
self.ok_builtin_modules = list
self.set_trusted_path()
self.make_builtin()
self.make_initial_modules()
# make_sys must be last because it adds the already created
@ -143,6 +164,22 @@ def __init__(self, hooks = None, verbose = 0):
self.loader = RModuleLoader(self.hooks, verbose)
self.importer = RModuleImporter(self.loader, verbose)
def set_trusted_path(self):
# Set the path from which dynamic modules may be loaded.
# Those dynamic modules must also occur in ok_builtin_modules
self.trusted_path = filter(os.path.isabs, sys.path)
def load_dynamic(self, name, filename, file):
if name not in self.ok_dynamic_modules:
raise ImportError, "untrusted dynamic module: %s" % name
if sys.modules.has_key(name):
src = sys.modules[key]
else:
import imp
src = imp.load_dynamic(name, filename, file)
dst = self.copy_except(src, [])
return dst
def make_initial_modules(self):
self.make_main()
self.make_osname()
@ -186,8 +223,12 @@ def make_sys(self):
def copy_except(self, src, exceptions):
dst = self.copy_none(src)
for name in dir(src):
if name not in exceptions:
setattr(dst, name, getattr(src, name))
setattr(dst, name, getattr(src, name))
for name in exceptions:
try:
delattr(dst, name)
except KeyError:
pass
return dst
def copy_only(self, src, names):