From 5ce8451d2893e3ce64d40e1835b6b2b2ad437f3c 2014-02-20 22:28:41
From: Julian Taylor <jtaylor.debian@googlemail.com>
Date: 2014-02-20 22:28:41
Subject: [PATCH] remove mktemp usage

mktemp is insecure, by the time the generated filename is used someone
else might have modified it.

---

diff --git a/IPython/core/page.py b/IPython/core/page.py
index e0aebd2..23fedb5 100644
--- a/IPython/core/page.py
+++ b/IPython/core/page.py
@@ -208,16 +208,19 @@ def page(strng, start=0, screen_lines=0, pager_cmd=None):
                 # The default WinXP 'type' command is failing on complex strings.
                 retval = 1
             else:
-                tmpname = tempfile.mktemp('.txt')
-                tmpfile = open(tmpname,'wt')
-                tmpfile.write(strng)
-                tmpfile.close()
-                cmd = "%s < %s" % (pager_cmd,tmpname)
-                if os.system(cmd):
-                  retval = 1
-                else:
-                  retval = None
-                os.remove(tmpname)
+                fd, tmpname = tempfile.mkstemp('.txt')
+                try:
+                    os.close(fd)
+                    with open(tmpname, 'wt') as tmpfile:
+                        tmpfile.write(strng)
+                        cmd = "%s < %s" % (pager_cmd, tmpname)
+                    # tmpfile needs to be closed for windows
+                    if os.system(cmd):
+                        retval = 1
+                    else:
+                        retval = None
+                finally:
+                    os.remove(tmpname)
         else:
             try:
                 retval = None
diff --git a/IPython/kernel/connect.py b/IPython/kernel/connect.py
index 894ca1d..f889ab9 100644
--- a/IPython/kernel/connect.py
+++ b/IPython/kernel/connect.py
@@ -95,7 +95,8 @@ def write_connection_file(fname=None, shell_port=0, iopub_port=0, stdin_port=0, 
         ip = localhost()
     # default to temporary connector file
     if not fname:
-        fname = tempfile.mktemp('.json')
+        fd, fname = tempfile.mkstemp('.json')
+        os.close(fd)
     
     # Find open ports as necessary.
     
diff --git a/IPython/parallel/tests/test_client.py b/IPython/parallel/tests/test_client.py
index c8ebef6..fd70b6d 100644
--- a/IPython/parallel/tests/test_client.py
+++ b/IPython/parallel/tests/test_client.py
@@ -20,7 +20,6 @@ from __future__ import division
 
 import time
 from datetime import datetime
-from tempfile import mktemp
 
 import zmq
 
diff --git a/IPython/parallel/tests/test_view.py b/IPython/parallel/tests/test_view.py
index e1ff878..cfefb7e 100644
--- a/IPython/parallel/tests/test_view.py
+++ b/IPython/parallel/tests/test_view.py
@@ -21,7 +21,7 @@ import sys
 import platform
 import time
 from collections import namedtuple
-from tempfile import mktemp
+from tempfile import NamedTemporaryFile
 
 import zmq
 from nose.plugins.attrib import attr
@@ -164,13 +164,12 @@ class TestView(ClusterTestCase):
     
     def test_run_newline(self):
         """test that run appends newline to files"""
-        tmpfile = mktemp()
-        with open(tmpfile, 'w') as f:
+        with NamedTemporaryFile('w', delete=False) as f:
             f.write("""def g():
                 return 5
                 """)
         v = self.client[-1]
-        v.run(tmpfile, block=True)
+        v.run(f.name, block=True)
         self.assertEqual(v.apply_sync(lambda f: f(), pmod.Reference('g')), 5)
 
     def test_apply_tracked(self):
diff --git a/IPython/testing/tools.py b/IPython/testing/tools.py
index daaf20f..c9772de 100644
--- a/IPython/testing/tools.py
+++ b/IPython/testing/tools.py
@@ -152,7 +152,9 @@ def default_config():
     config.TerminalInteractiveShell.colors = 'NoColor'
     config.TerminalTerminalInteractiveShell.term_title = False,
     config.TerminalInteractiveShell.autocall = 0
-    config.HistoryManager.hist_file = tempfile.mktemp(u'test_hist.sqlite')
+    f = tempfile.NamedTemporaryFile(suffix=u'test_hist.sqlite', delete=False)
+    config.HistoryManager.hist_file = f.name
+    f.close()
     config.HistoryManager.db_cache_size = 10000
     return config