summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2018-10-20 00:49:00 (GMT)
committerGitHub <noreply@github.com>2018-10-20 00:49:00 (GMT)
commitd9a2665fc4573c4d311a89750737ad4cc3310252 (patch)
tree4b1e7f0ce8180491413dd298c763bf06506559ef
parent75ee130c39e73730535d94923fd8322ef616cb83 (diff)
downloadcpython-d9a2665fc4573c4d311a89750737ad4cc3310252.zip
cpython-d9a2665fc4573c4d311a89750737ad4cc3310252.tar.gz
cpython-d9a2665fc4573c4d311a89750737ad4cc3310252.tar.bz2
bpo-32890, os: Use errno instead of GetLastError() in execve() and truncate() (GH-5784)
path_error() uses GetLastError() on Windows, but some os functions are implemented via CRT APIs which report errors via errno. This may result in raising OSError with invalid error code (such as zero). Introduce posix_path_error() function and use it where appropriate. (cherry picked from commit 834603112e6ca35944dd21105b01fca562dc3241) Co-authored-by: Alexey Izbyshev <izbyshev@ispras.ru>
-rw-r--r--Lib/test/test_os.py10
-rw-r--r--Misc/NEWS.d/next/Windows/2018-03-08-20-02-38.bpo-32890.3jzFzY.rst2
-rw-r--r--Modules/posixmodule.c18
3 files changed, 27 insertions, 3 deletions
diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py
index 8339f84..9e35d55 100644
--- a/Lib/test/test_os.py
+++ b/Lib/test/test_os.py
@@ -1582,6 +1582,16 @@ class ExecTests(unittest.TestCase):
with self.assertRaises(ValueError):
os.execve(args[0], args, newenv)
+ @unittest.skipUnless(sys.platform == "win32", "Win32-specific test")
+ def test_execve_with_empty_path(self):
+ # bpo-32890: Check GetLastError() misuse
+ try:
+ os.execve('', ['arg'], {})
+ except OSError as e:
+ self.assertTrue(e.winerror is None or e.winerror != 0)
+ else:
+ self.fail('No OSError raised')
+
@unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
class Win32ErrorTests(unittest.TestCase):
diff --git a/Misc/NEWS.d/next/Windows/2018-03-08-20-02-38.bpo-32890.3jzFzY.rst b/Misc/NEWS.d/next/Windows/2018-03-08-20-02-38.bpo-32890.3jzFzY.rst
new file mode 100644
index 0000000..e8a63b3
--- /dev/null
+++ b/Misc/NEWS.d/next/Windows/2018-03-08-20-02-38.bpo-32890.3jzFzY.rst
@@ -0,0 +1,2 @@
+Fix usage of GetLastError() instead of errno in os.execve() and
+os.truncate().
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index af6b9dc..7358c39 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -1341,13 +1341,19 @@ win32_error_object(const char* function, PyObject* filename)
#endif /* MS_WINDOWS */
static PyObject *
+posix_path_object_error(PyObject *path)
+{
+ return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
+}
+
+static PyObject *
path_object_error(PyObject *path)
{
#ifdef MS_WINDOWS
return PyErr_SetExcFromWindowsErrWithFilenameObject(
PyExc_OSError, 0, path);
#else
- return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
+ return posix_path_object_error(path);
#endif
}
@@ -1369,6 +1375,12 @@ path_error(path_t *path)
}
static PyObject *
+posix_path_error(path_t *path)
+{
+ return posix_path_object_error(path->object);
+}
+
+static PyObject *
path_error2(path_t *path, path_t *path2)
{
return path_object_error2(path->object, path2->object);
@@ -5041,7 +5053,7 @@ os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
/* If we get here it's definitely an error */
- path_error(path);
+ posix_path_error(path);
free_string_array(envlist, envc);
fail:
@@ -8770,7 +8782,7 @@ os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
_Py_END_SUPPRESS_IPH
Py_END_ALLOW_THREADS
if (result < 0)
- return path_error(path);
+ return posix_path_error(path);
Py_RETURN_NONE;
}