Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions Lib/test/test_os.py
Original file line number Diff line number Diff line change
Expand Up @@ -1589,6 +1589,16 @@ def test_execve_invalid_env(self):
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')

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note for future PRs: self.assertRaises should be used in such cases.
It makes the intent of the test clearer, and prevent adding the else block which lowers test coverage (as it is not reached unless the code is buggy).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, thanks for the advice.



@unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
class Win32ErrorTests(unittest.TestCase):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix usage of GetLastError() instead of errno in os.execve() and
os.truncate().
18 changes: 15 additions & 3 deletions Modules/posixmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -1431,14 +1431,20 @@ 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
}

Expand All @@ -1459,6 +1465,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)
{
Expand Down Expand Up @@ -5090,7 +5102,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:
Expand Down Expand Up @@ -9251,7 +9263,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;
}
Expand Down