]> granicus.if.org Git - python/commitdiff
bpo-32890, os: Use errno instead of GetLastError() in execve() and truncate() (GH...
authorAlexey Izbyshev <izbyshev@ispras.ru>
Sat, 20 Oct 2018 00:28:22 +0000 (03:28 +0300)
committerVictor Stinner <vstinner@redhat.com>
Sat, 20 Oct 2018 00:28:22 +0000 (02:28 +0200)
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.

Lib/test/test_os.py
Misc/NEWS.d/next/Windows/2018-03-08-20-02-38.bpo-32890.3jzFzY.rst [new file with mode: 0644]
Modules/posixmodule.c

index 6dbc25561237ad07296c914a8b078f41d5d8767a..3f6e48f0c8e69c53f451b33fc8958a1f824b045f 100644 (file)
@@ -1589,6 +1589,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 (file)
index 0000000..e8a63b3
--- /dev/null
@@ -0,0 +1,2 @@
+Fix usage of GetLastError() instead of errno in os.execve() and
+os.truncate().
index 23552bea4cae318c46f413795ff4504fa2f41a21..9ccdc8eff1bd5ca864507a9fc8faeec8e47efd43 100644 (file)
@@ -1455,6 +1455,12 @@ 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)
 {
@@ -1462,7 +1468,7 @@ path_object_error(PyObject *path)
     return PyErr_SetExcFromWindowsErrWithFilenameObject(
                 PyExc_OSError, 0, path);
 #else
-    return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
+    return posix_path_object_error(path);
 #endif
 }
 
@@ -1483,6 +1489,12 @@ path_error(path_t *path)
     return path_object_error(path->object);
 }
 
+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)
 {
@@ -5141,7 +5153,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:
@@ -9477,7 +9489,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;
 }