Applying patch

[#636769] Fix for major rexec bugs

* Lib/rexec.py
  (FileBase): Added 'xreadlines' and '__iter__' to allowed file methods.
  (FileWrapper.__init__): Removed unnecessary self.f variable, which gave
  direct access to the file object.
  (RExec): Added 'xreadlines' and '_weakref' to allowed modules.
  (RExec.r_open): Convert string subclasses to a real string classes
  before doing comparisons with mode parameter.

* Lib/ihooks.py
  (BasicModuleImporter.import_module/reload/unload): Convert the module
  name to a real string before working with it.
  (ModuleImporter.import_module/import_it/reload): Convert the module
  name to a real strings before working with it.

* Misc/NEWS
  Document the change.
diff --git a/Lib/ihooks.py b/Lib/ihooks.py
index 7b00837..f01862d 100644
--- a/Lib/ihooks.py
+++ b/Lib/ihooks.py
@@ -352,6 +352,7 @@
         return self.loader.set_hooks(hooks)
 
     def import_module(self, name, globals={}, locals={}, fromlist=[]):
+        name = str(name)
         if name in self.modules:
             return self.modules[name] # Fast path
         stuff = self.loader.find_module(name)
@@ -360,14 +361,14 @@
         return self.loader.load_module(name, stuff)
 
     def reload(self, module, path = None):
-        name = module.__name__
+        name = str(module.__name__)
         stuff = self.loader.find_module(name, path)
         if not stuff:
             raise ImportError, "Module %s not found for reload" % name
         return self.loader.load_module(name, stuff)
 
     def unload(self, module):
-        del self.modules[module.__name__]
+        del self.modules[str(module.__name__)]
         # XXX Should this try to clear the module's namespace?
 
     def install(self):
@@ -394,7 +395,7 @@
 
     def import_module(self, name, globals=None, locals=None, fromlist=None):
         parent = self.determine_parent(globals)
-        q, tail = self.find_head_package(parent, name)
+        q, tail = self.find_head_package(parent, str(name))
         m = self.load_tail(q, tail)
         if not fromlist:
             return q
@@ -480,16 +481,18 @@
             path = parent and parent.__path__
         except AttributeError:
             return None
+        partname = str(partname)
         stuff = self.loader.find_module(partname, path)
         if not stuff:
             return None
+        fqname = str(fqname)
         m = self.loader.load_module(fqname, stuff)
         if parent:
             setattr(parent, partname, m)
         return m
 
     def reload(self, module):
-        name = module.__name__
+        name = str(module.__name__)
         if '.' not in name:
             return self.import_it(name, name, None, force_load=1)
         i = name.rfind('.')
diff --git a/Lib/rexec.py b/Lib/rexec.py
index d399545..b1a1427 100644
--- a/Lib/rexec.py
+++ b/Lib/rexec.py
@@ -29,7 +29,8 @@
 class FileBase:
 
     ok_file_methods = ('fileno', 'flush', 'isatty', 'read', 'readline',
-            'readlines', 'seek', 'tell', 'write', 'writelines')
+            'readlines', 'seek', 'tell', 'write', 'writelines', 'xreadlines',
+            '__iter__')
 
 
 class FileWrapper(FileBase):
@@ -37,7 +38,6 @@
     # XXX This is just like a Bastion -- should use that!
 
     def __init__(self, f):
-        self.f = f
         for m in self.ok_file_methods:
             if not hasattr(self, m) and hasattr(f, m):
                 setattr(self, m, getattr(f, m))
@@ -137,7 +137,8 @@
                           'cmath', 'errno', 'imageop',
                           'marshal', 'math', 'md5', 'operator',
                           'parser', 'regex', 'pcre', 'rotor', 'select',
-                          'sha', '_sre', 'strop', 'struct', 'time')
+                          'sha', '_sre', 'strop', 'struct', 'time',
+                          'xreadlines', '_weakref')
 
     ok_posix_names = ('error', 'fstat', 'listdir', 'lstat', 'readlink',
                       'stat', 'times', 'uname', 'getpid', 'getppid',
@@ -515,6 +516,7 @@
         used to change the policies enforced by a restricted environment.
 
         """
+        mode = str(mode)
         if mode not in ('r', 'rb'):
             raise IOError, "can't open files for writing in restricted mode"
         return open(file, mode, buf)
diff --git a/Misc/NEWS b/Misc/NEWS
index 7eb828f..12df9ec 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -667,6 +667,9 @@
   unix environment even if DISPLAY was not set. Also, support for
   skipstone browser was included.
 
+- Fixed bug #636769: rexec would run unallowed code if subclasses of
+  strings were used as parameters for certain functions.
+
 Tools/Demos
 -----------