Kaydet (Commit) 2240ac1e authored tarafından Richard Oudkerk's avatar Richard Oudkerk

Issue #15261: Stop os.stat(fd) crashing on Windows when fd not open.

üst 74de1536
...@@ -70,11 +70,16 @@ applications should use string objects to access all files. ...@@ -70,11 +70,16 @@ applications should use string objects to access all files.
.. function:: exists(path) .. function:: exists(path)
Return ``True`` if *path* refers to an existing path. Returns ``False`` for Return ``True`` if *path* refers to an existing path or an open
broken symbolic links. On some platforms, this function may return ``False`` if file descriptor. Returns ``False`` for broken symbolic links. On
permission is not granted to execute :func:`os.stat` on the requested file, even some platforms, this function may return ``False`` if permission is
not granted to execute :func:`os.stat` on the requested file, even
if the *path* physically exists. if the *path* physically exists.
.. versionchanged:: 3.3
*path* can now be an integer: ``True`` is returned if it is an
open file descriptor, ``False`` otherwise.
.. function:: lexists(path) .. function:: lexists(path)
......
...@@ -146,6 +146,16 @@ class GenericTest(unittest.TestCase): ...@@ -146,6 +146,16 @@ class GenericTest(unittest.TestCase):
f.close() f.close()
support.unlink(support.TESTFN) support.unlink(support.TESTFN)
@unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()")
def test_exists_fd(self):
r, w = os.pipe()
try:
self.assertTrue(self.pathmodule.exists(r))
finally:
os.close(r)
os.close(w)
self.assertFalse(self.pathmodule.exists(r))
def test_isdir(self): def test_isdir(self):
self.assertIs(self.pathmodule.isdir(support.TESTFN), False) self.assertIs(self.pathmodule.isdir(support.TESTFN), False)
f = open(support.TESTFN, "wb") f = open(support.TESTFN, "wb")
......
...@@ -473,6 +473,19 @@ class StatAttributeTests(unittest.TestCase): ...@@ -473,6 +473,19 @@ class StatAttributeTests(unittest.TestCase):
return return
self.fail("Could not stat pagefile.sys") self.fail("Could not stat pagefile.sys")
@unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()")
def test_15261(self):
# Verify that stat'ing a closed fd does not cause crash
r, w = os.pipe()
try:
os.stat(r) # should not raise error
finally:
os.close(r)
os.close(w)
with self.assertRaises(OSError) as ctx:
os.stat(r)
self.assertEqual(ctx.exception.errno, errno.EBADF)
from test import mapping_tests from test import mapping_tests
class EnvironTests(mapping_tests.BasicTestMappingProtocol): class EnvironTests(mapping_tests.BasicTestMappingProtocol):
......
...@@ -23,6 +23,8 @@ Core and Builtins ...@@ -23,6 +23,8 @@ Core and Builtins
Library Library
------- -------
- Issue #15261: Stop os.stat(fd) crashing on Windows when fd not open.
- Issue #15166: Implement imp.get_tag() using sys.implementation.cache_tag. - Issue #15166: Implement imp.get_tag() using sys.implementation.cache_tag.
- Issue #15210: Catch KeyError when imprortlib.__init__ can't find - Issue #15210: Catch KeyError when imprortlib.__init__ can't find
......
...@@ -1829,7 +1829,10 @@ win32_fstat(int file_number, struct win32_stat *result) ...@@ -1829,7 +1829,10 @@ win32_fstat(int file_number, struct win32_stat *result)
HANDLE h; HANDLE h;
int type; int type;
h = (HANDLE)_get_osfhandle(file_number); if (!_PyVerify_fd(file_number))
h = INVALID_HANDLE_VALUE;
else
h = (HANDLE)_get_osfhandle(file_number);
/* Protocol violation: we explicitly clear errno, instead of /* Protocol violation: we explicitly clear errno, instead of
setting it to a POSIX error. Callers should use GetLastError. */ setting it to a POSIX error. Callers should use GetLastError. */
...@@ -8244,8 +8247,6 @@ posix_fstat(PyObject *self, PyObject *args) ...@@ -8244,8 +8247,6 @@ posix_fstat(PyObject *self, PyObject *args)
/* on OpenVMS we must ensure that all bytes are written to the file */ /* on OpenVMS we must ensure that all bytes are written to the file */
fsync(fd); fsync(fd);
#endif #endif
if (!_PyVerify_fd(fd))
return posix_error();
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
res = FSTAT(fd, &st); res = FSTAT(fd, &st);
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment