]> granicus.if.org Git - python/commitdiff
#3965: on Windows, open() crashes if the filename or the mode is invalid,
authorAmaury Forgeot d'Arc <amauryfa@gmail.com>
Thu, 25 Sep 2008 20:52:56 +0000 (20:52 +0000)
committerAmaury Forgeot d'Arc <amauryfa@gmail.com>
Thu, 25 Sep 2008 20:52:56 +0000 (20:52 +0000)
and if the filename is a unicode string.

Reviewed by Martin von Loewis.

Lib/test/test_file.py
Misc/NEWS
Objects/fileobject.c

index 7cfaef76fedfaca3e231ea44e493b6814d220676..b93bdbd9d0a5bd28c4b8e7ad64e945890d840c29 100644 (file)
@@ -134,6 +134,16 @@ class OtherFileTests(unittest.TestCase):
                 f.close()
                 self.fail('%r is an invalid file mode' % mode)
 
+        # Some invalid modes fail on Windows, but pass on Unix
+        # Issue3965: avoid a crash on Windows when filename is unicode
+        for name in (TESTFN, unicode(TESTFN), unicode(TESTFN + '\t')):
+            try:
+                f = open(name, "rr")
+            except IOError:
+                pass
+            else:
+                f.close()
+
     def testStdin(self):
         # This causes the interpreter to exit on OSF1 v5.1.
         if sys.platform != 'osf1V5':
index 80e524d25281b75088cc57cda68f4da7c1f1717e..660e88a728de9b258b9fea70c455b9dcb74b235e 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,9 @@ What's New in Python 2.6 final
 Core and Builtins
 -----------------
 
+- Issue #3965: Fixed a crash on Windows when open() is given an invalid
+  filename or mode, and the filename is a unicode string.
+
 - Bug #3951: Py_USING_MEMORY_DEBUGGER should not be enabled by default.
 
 Library
index a8e95a269756373e931bf1aa4ee86671e97fba24..b2051d79fe45737dce9d19e5b7d63ab179e8aed6 100644 (file)
@@ -305,10 +305,17 @@ open_the_file(PyFileObject *f, char *name, char *mode)
 #endif
                 /* EINVAL is returned when an invalid filename or
                  * an invalid mode is supplied. */
-               if (errno == EINVAL)
-                       PyErr_Format(PyExc_IOError,
-                                     "invalid filename: %s or mode: %s",
-                                    name, mode);
+               if (errno == EINVAL) {
+                       PyObject *v;
+                       char message[100];
+                       PyOS_snprintf(message, 100, 
+                           "invalid mode ('%.50s') or filename", mode);
+                       v = Py_BuildValue("(isO)", errno, message, f->f_name);
+                       if (v != NULL) {
+                               PyErr_SetObject(PyExc_IOError, v);
+                               Py_DECREF(v);
+                       }
+               }
                else
                        PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, f->f_name);
                f = NULL;