mirror of https://github.com/python/cpython.git
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:
parent
9e6aa9d55b
commit
fdd45cb858
65
Lib/rexec.py
65
Lib/rexec.py
|
@ -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):
|
||||
|
|
Loading…
Reference in New Issue