From: Amaury Forgeot d'Arc Date: Thu, 25 Sep 2008 20:52:56 +0000 (+0000) Subject: #3965: on Windows, open() crashes if the filename or the mode is invalid, X-Git-Tag: v2.6~39 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=17617a07d1f2d2ffb6b0f77be8926f54cd0f4ae8;p=thirdparty%2FPython%2Fcpython.git #3965: on Windows, open() crashes if the filename or the mode is invalid, and if the filename is a unicode string. Reviewed by Martin von Loewis. --- diff --git a/Lib/test/test_file.py b/Lib/test/test_file.py index 7cfaef76fedf..b93bdbd9d0a5 100644 --- a/Lib/test/test_file.py +++ b/Lib/test/test_file.py @@ -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': diff --git a/Misc/NEWS b/Misc/NEWS index 80e524d25281..660e88a728de 100644 --- 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 diff --git a/Objects/fileobject.c b/Objects/fileobject.c index a8e95a269756..b2051d79fe45 100644 --- a/Objects/fileobject.c +++ b/Objects/fileobject.c @@ -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;