From a5682f0ba8984489e660136c26d19a99dc41cd40 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Sun, 29 Mar 2009 19:03:52 +0000 Subject: Merged revisions 70690,70692 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/py3k ........ r70690 | antoine.pitrou | 2009-03-29 20:40:13 +0200 (dim., 29 mars 2009) | 3 lines Fix leak in _fileio.c (patch by Hirokazu Yamamoto) ........ r70692 | antoine.pitrou | 2009-03-29 20:55:12 +0200 (dim., 29 mars 2009) | 4 lines Plug another leak, and finally add a test for #1174606 (read() from /dev/zero). The leak was the reason my previous attempts at testing failed... ........ --- Lib/test/test_io.py | 16 ++++++++++++++++ Modules/_fileio.c | 2 ++ 2 files changed, 18 insertions(+) diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index 598e391..98fcbf9 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -305,6 +305,22 @@ class IOTest(unittest.TestCase): file = io.open(f.fileno(), "r", closefd=False) self.assertEqual(file.buffer.raw.closefd, False) + def test_unbounded_file(self): + # Issue #1174606: reading from an unbounded stream such as /dev/zero. + zero = "/dev/zero" + if not os.path.exists(zero): + return # /dev/zero does not exist + if sys.maxsize > 0x7FFFFFFF: + return # test can only run in a 32-bit address space + if support.real_max_memuse < support._2G: + return # test requires at least 2GB of memory + with open(zero, "rb", buffering=0) as f: + self.assertRaises(OverflowError, f.read) + with open(zero, "rb") as f: + self.assertRaises(OverflowError, f.read) + with open(zero, "r") as f: + self.assertRaises(OverflowError, f.read) + class MemorySeekTestMixin: diff --git a/Modules/_fileio.c b/Modules/_fileio.c index 919fdea..f718d70 100644 --- a/Modules/_fileio.c +++ b/Modules/_fileio.c @@ -465,6 +465,7 @@ fileio_readall(PyFileIOObject *self) PyErr_SetString(PyExc_OverflowError, "unbounded read returned more bytes " "than a Python string can hold "); + Py_DECREF(result); return NULL; } @@ -541,6 +542,7 @@ fileio_read(PyFileIOObject *self, PyObject *args) Py_END_ALLOW_THREADS if (n < 0) { + Py_DECREF(bytes); if (errno == EAGAIN) Py_RETURN_NONE; PyErr_SetFromErrno(PyExc_IOError); -- cgit v0.12