From 77df4a85958a5c0633a4dbb1007db3fc2b8efd91 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Fri, 13 Mar 2009 23:46:17 +0000 Subject: [PATCH] Merged revisions 70352 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/py3k ........ r70352 | antoine.pitrou | 2009-03-14 00:42:55 +0100 (sam., 14 mars 2009) | 4 lines Issue #5016: FileIO.seekable() could return False if the file position was negative when truncated to a C int. Patch by Victor Stinner. ........ --- Lib/test/test_largefile.py | 10 ++++++++++ Misc/NEWS | 3 +++ Modules/_fileio.c | 14 ++++++++------ 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/Lib/test/test_largefile.py b/Lib/test/test_largefile.py index 8060ea04e855..8cb4a176300b 100644 --- a/Lib/test/test_largefile.py +++ b/Lib/test/test_largefile.py @@ -131,6 +131,15 @@ class TestCase(unittest.TestCase): f.seek(0) self.assertEqual(len(f.read()), 1) # else wasn't truncated + def test_seekable(self): + # Issue #5016; seekable() can return False when the current position + # is negative when truncated to an int. + for pos in (2**31-1, 2**31, 2**31+1): + with open(TESTFN, 'rb') as f: + f.seek(pos) + self.assert_(f.seekable()) + + def test_main(): # On Windows and Mac OSX this test comsumes large resources; It # takes a long time to build the >2GB file and takes >2GB of disk @@ -165,6 +174,7 @@ def test_main(): with open(TESTFN, 'w') as f: if hasattr(f, 'truncate'): suite.addTest(TestCase('test_truncate')) + suite.addTest(TestCase('test_seekable')) unlink(TESTFN) try: run_unittest(suite) diff --git a/Misc/NEWS b/Misc/NEWS index 97b8fd1d9720..b0758046418f 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -24,6 +24,9 @@ Core and Builtins Library ------- +- Issue #5016: FileIO.seekable() could return False if the file position + was negative when truncated to a C int. Patch by Victor Stinner. + - Issue #5179: Fixed subprocess handle leak on failure on windows. - Issue #5282: Fixed mmap resize on 32bit windows and unix. When offset > 0, diff --git a/Modules/_fileio.c b/Modules/_fileio.c index 7fe37ec657c3..bee19fe511ee 100644 --- a/Modules/_fileio.c +++ b/Modules/_fileio.c @@ -58,6 +58,8 @@ PyTypeObject PyFileIO_Type; static PyObject * portable_lseek(int fd, PyObject *posobj, int whence); +static PyObject *portable_lseek(int fd, PyObject *posobj, int whence); + /* Returns 0 on success, -1 with exception set on failure. */ static int internal_close(PyFileIOObject *self) @@ -396,14 +398,14 @@ fileio_seekable(PyFileIOObject *self) if (self->fd < 0) return err_closed(); if (self->seekable < 0) { - int ret; - Py_BEGIN_ALLOW_THREADS - ret = lseek(self->fd, 0, SEEK_CUR); - Py_END_ALLOW_THREADS - if (ret < 0) + PyObject *pos = portable_lseek(self->fd, NULL, SEEK_CUR); + if (pos == NULL) { + PyErr_Clear(); self->seekable = 0; - else + } else { + Py_DECREF(pos); self->seekable = 1; + } } return PyBool_FromLong((long) self->seekable); } -- 2.47.3