mirror of
https://github.com/python/cpython.git
synced 2025-07-24 19:54:21 +00:00
Issue #15261: Stop os.stat(fd) crashing on Windows when fd not open.
This commit is contained in:
parent
74de153681
commit
2240ac1eae
5 changed files with 37 additions and 6 deletions
|
@ -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):
|
||||||
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):
|
||||||
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
|
||||||
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)
|
||||||
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)
|
||||||
/* 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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue