[Python-checkins] python/dist/src/Lib rexec.py,1.40,1.41

gvanrossum@users.sourceforge.net gvanrossum@users.sourceforge.net
Sat, 14 Sep 2002 23:00:46 -0700


Update of /cvsroot/python/python/dist/src/Lib
In directory usw-pr-cvs1:/tmp/cvs-serv25571

Modified Files:
	rexec.py 
Log Message:
Address SF bug #577530: del __builtins__ breaks out of rexec

Using the suggestion there: add_module() forces __builtin__ back; this
fixes r_exec, r_eval, r_execfile.  The interactive console had to be
fixed separately, because it doesn't use r_exec, but relies on the
'locals' dict having the right __builtins__.  Fixed this by
subclassing InteractiveConsole and overriding runcode(), which does
the exec.  This changes the banner output slightly: instead of
starting with *** RESTRICTED ***, a subtler (RestrictedConsole) is
printed before the first >>> prompt.

Also import readline (if it exists) when the interactive console is
used, for more convenient input editing and history.

This does not mean that rexec is now considered safe!  But for those
willing to take the risk, it's safer than before.  (Note that a safety
analysis of the code module would be wise if you plan to use the
interactive console for real -- I've only ever used it to play with
restricted mode.)

This should be backported to 2.2 and 2.1.


Index: rexec.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/rexec.py,v
retrieving revision 1.40
retrieving revision 1.41
diff -C2 -d -r1.40 -r1.41
*** rexec.py	14 Jun 2002 13:54:26 -0000	1.40
--- rexec.py	15 Sep 2002 06:00:43 -0000	1.41
***************
*** 289,295 ****
  
      def add_module(self, mname):
!         if mname in self.modules:
!             return self.modules[mname]
!         self.modules[mname] = m = self.hooks.new_module(mname)
          m.__builtins__ = self.modules['__builtin__']
          return m
--- 289,295 ----
  
      def add_module(self, mname):
!         m = self.modules.get(mname)
!         if m is None:
!             self.modules[mname] = m = self.hooks.new_module(mname)
          m.__builtins__ = self.modules['__builtin__']
          return m
***************
*** 553,563 ****
              return 1
      if fp.isatty():
          import code
          try:
!             code.interact(
!                 "*** RESTRICTED *** Python %s on %s\n"
!                 'Type "help", "copyright", "credits" or "license" '
!                 "for more information." % (sys.version, sys.platform),
!                 local=r.modules['__main__'].__dict__)
          except SystemExit, n:
              return n
--- 553,567 ----
              return 1
      if fp.isatty():
+         try:
+             import readline
+         except ImportError:
+             pass
          import code
+         class RestrictedConsole(code.InteractiveConsole):
+             def runcode(self, co):
+                 self.locals['__builtins__'] = r.modules['__builtin__']
+                 r.s_apply(code.InteractiveConsole.runcode, (self, co))
          try:
!             RestrictedConsole(r.modules['__main__'].__dict__).interact()
          except SystemExit, n:
              return n