diff options
author | Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | 2018-12-01 12:53:36 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-12-01 12:53:36 (GMT) |
commit | 013832ff964a0b3b59e04a07a33bae65c1c3ae84 (patch) | |
tree | 83e1529472b688fa58402ab89eff2cd8816f260b | |
parent | 1e28daf0b58c9c3a08e98b3a3caebb53acf9a617 (diff) | |
download | cpython-013832ff964a0b3b59e04a07a33bae65c1c3ae84.zip cpython-013832ff964a0b3b59e04a07a33bae65c1c3ae84.tar.gz cpython-013832ff964a0b3b59e04a07a33bae65c1c3ae84.tar.bz2 |
bpo-35371: Fix possible crash in os.utime() on Windows. (GH-10844)
(cherry picked from commit 32bc11c33cf5ccea165b5f4ac3799f02fdf9c76a)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
-rw-r--r-- | Lib/test/test_os.py | 23 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2018-12-01-13-44-12.bpo-35371.fTAwlX.rst | 2 | ||||
-rw-r--r-- | Modules/posixmodule.c | 37 |
3 files changed, 40 insertions, 22 deletions
diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 9e35d55..7a839c8 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -660,6 +660,29 @@ class UtimeTests(unittest.TestCase): # seconds and nanoseconds parameters are mutually exclusive with self.assertRaises(ValueError): os.utime(self.fname, (5, 5), ns=(5, 5)) + with self.assertRaises(TypeError): + os.utime(self.fname, [5, 5]) + with self.assertRaises(TypeError): + os.utime(self.fname, (5,)) + with self.assertRaises(TypeError): + os.utime(self.fname, (5, 5, 5)) + with self.assertRaises(TypeError): + os.utime(self.fname, ns=[5, 5]) + with self.assertRaises(TypeError): + os.utime(self.fname, ns=(5,)) + with self.assertRaises(TypeError): + os.utime(self.fname, ns=(5, 5, 5)) + + if os.utime not in os.supports_follow_symlinks: + with self.assertRaises(NotImplementedError): + os.utime(self.fname, (5, 5), follow_symlinks=False) + if os.utime not in os.supports_fd: + with open(self.fname, 'wb', 0) as fp: + with self.assertRaises(TypeError): + os.utime(fp.fileno(), (5, 5)) + if os.utime not in os.supports_dir_fd: + with self.assertRaises(NotImplementedError): + os.utime(self.fname, (5, 5), dir_fd=0) from test import mapping_tests diff --git a/Misc/NEWS.d/next/Library/2018-12-01-13-44-12.bpo-35371.fTAwlX.rst b/Misc/NEWS.d/next/Library/2018-12-01-13-44-12.bpo-35371.fTAwlX.rst new file mode 100644 index 0000000..f40d139 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-12-01-13-44-12.bpo-35371.fTAwlX.rst @@ -0,0 +1,2 @@ +Fixed possible crash in ``os.utime()`` on Windows when pass incorrect +arguments. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index b7091ca..03825c3 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -4589,7 +4589,6 @@ os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns, int result; #endif - PyObject *return_value = NULL; utime_t utime; memset(&utime, 0, sizeof(utime_t)); @@ -4598,7 +4597,7 @@ os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns, PyErr_SetString(PyExc_ValueError, "utime: you may specify either 'times'" " or 'ns' but not both"); - goto exit; + return NULL; } if (times && (times != Py_None)) { @@ -4608,14 +4607,14 @@ os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns, PyErr_SetString(PyExc_TypeError, "utime: 'times' must be either" " a tuple of two ints or None"); - goto exit; + return NULL; } utime.now = 0; if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0), &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 || _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1), &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) { - goto exit; + return NULL; } utime.atime_s = a_sec; utime.atime_ns = a_nsec; @@ -4626,14 +4625,14 @@ os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns, if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) { PyErr_SetString(PyExc_TypeError, "utime: 'ns' must be a tuple of two ints"); - goto exit; + return NULL; } utime.now = 0; if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0), &utime.atime_s, &utime.atime_ns) || !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1), &utime.mtime_s, &utime.mtime_ns)) { - goto exit; + return NULL; } } else { @@ -4643,20 +4642,20 @@ os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns, #if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS) if (follow_symlinks_specified("utime", follow_symlinks)) - goto exit; + return NULL; #endif if (path_and_dir_fd_invalid("utime", path, dir_fd) || dir_fd_and_fd_invalid("utime", dir_fd, path->fd) || fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks)) - goto exit; + return NULL; #if !defined(HAVE_UTIMENSAT) if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) { PyErr_SetString(PyExc_ValueError, "utime: cannot use dir_fd and follow_symlinks " "together on this platform"); - goto exit; + return NULL; } #endif @@ -4668,7 +4667,7 @@ os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns, Py_END_ALLOW_THREADS if (hFile == INVALID_HANDLE_VALUE) { path_error(path); - goto exit; + return NULL; } if (utime.now) { @@ -4685,8 +4684,10 @@ os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns, something is wrong with the file, when it also could be the time stamp that gives a problem. */ PyErr_SetFromWindowsErr(0); - goto exit; + CloseHandle(hFile); + return NULL; } + CloseHandle(hFile); #else /* MS_WINDOWS */ Py_BEGIN_ALLOW_THREADS @@ -4714,21 +4715,13 @@ os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns, if (result < 0) { /* see previous comment about not putting filename in error here */ - return_value = posix_error(); - goto exit; + posix_error(); + return NULL; } #endif /* MS_WINDOWS */ - Py_INCREF(Py_None); - return_value = Py_None; - -exit: -#ifdef MS_WINDOWS - if (hFile != INVALID_HANDLE_VALUE) - CloseHandle(hFile); -#endif - return return_value; + Py_RETURN_NONE; } /* Process operations */ |