From 6dbab8a6e0b4d247893856c91d26671a0c3912e2 Mon Sep 17 00:00:00 2001 From: Xiang Zhang Date: Fri, 14 Apr 2017 14:46:29 +0800 Subject: [PATCH 1/4] add missing iter(self) in _io._IOBase.readlines --- Lib/test/test_io.py | 1 + Modules/_io/iobase.c | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index 929865d9565998..32f76a6c627186 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -3510,6 +3510,7 @@ def test_io_after_close(self): self.assertRaises(ValueError, f.readinto1, bytearray(1024)) self.assertRaises(ValueError, f.readline) self.assertRaises(ValueError, f.readlines) + self.assertRaises(ValueError, f.readlines, 1) self.assertRaises(ValueError, f.seek, 0) self.assertRaises(ValueError, f.tell) self.assertRaises(ValueError, f.truncate) diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c index 75cfe59624bfb9..3c42c9758c705d 100644 --- a/Modules/_io/iobase.c +++ b/Modules/_io/iobase.c @@ -666,7 +666,13 @@ _io__IOBase_readlines_impl(PyObject *self, Py_ssize_t hint) } while (1) { - PyObject *line = PyIter_Next(self); + PyObject *it, *line; + it = PyObject_GetIter(self); + if (it == NULL) { + Py_DECREF(result); + return NULL; + } + line = PyIter_Next(it); if (line == NULL) { if (PyErr_Occurred()) { Py_DECREF(result); From 634c42b51dde755d7585625cff3a843bfc6fdd87 Mon Sep 17 00:00:00 2001 From: Xiang Zhang Date: Fri, 14 Apr 2017 14:49:54 +0800 Subject: [PATCH 2/4] add NEWS entry --- Misc/NEWS | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS index 440f0b25cb682b..5bb23b3cc8e4f3 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -306,12 +306,15 @@ Extension Modules Library ------- -- bpo-29692: Fixed arbitrary unchaining of RuntimeError exceptions in - contextlib.contextmanager. - Patch by Siddharth Velankar. + +- bpo-30068: _io._IOBase.readlines will check if it's closed first when + hint is present. + +- bpo-29692: Fixed arbitrary unchaining of RuntimeError exceptions in + contextlib.contextmanager. Patch by Siddharth Velankar. - bpo-26187: Test that sqlite3 trace callback is not called multiple - times when schema is changing. Indirectly fixed by switching to + times when schema is changing. Indirectly fixed by switching to use sqlite3_prepare_v2() in bpo-9303. Patch by Aviv Palivoda. - bpo-30017: Allowed calling the close() method of the zip entry writer object From 8e23a53f81d369695d137f57445250938cec2d0e Mon Sep 17 00:00:00 2001 From: Xiang Zhang Date: Fri, 14 Apr 2017 15:46:28 +0800 Subject: [PATCH 3/4] fix foolish mistake --- Misc/NEWS | 6 +++--- Modules/_io/iobase.c | 16 ++++++++-------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS index 5c5a823976586d..cd248e6f017d8e 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -310,12 +310,12 @@ Library - bpo-30068: _io._IOBase.readlines will check if it's closed first when hint is present. -- bpo-29692: Fixed arbitrary unchaining of RuntimeError exceptions in - contextlib.contextmanager. Patch by Siddharth Velankar. - - bpo-29694: Fixed race condition in pathlib mkdir with flags parents=True. Patch by Armin Rigo. +- bpo-29692: Fixed arbitrary unchaining of RuntimeError exceptions in + contextlib.contextmanager. Patch by Siddharth Velankar. + - bpo-26187: Test that sqlite3 trace callback is not called multiple times when schema is changing. Indirectly fixed by switching to use sqlite3_prepare_v2() in bpo-9303. Patch by Aviv Palivoda. diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c index 3c42c9758c705d..b0b040eaf55d7d 100644 --- a/Modules/_io/iobase.c +++ b/Modules/_io/iobase.c @@ -643,7 +643,7 @@ _io__IOBase_readlines_impl(PyObject *self, Py_ssize_t hint) /*[clinic end generated code: output=2f50421677fa3dea input=9400c786ea9dc416]*/ { Py_ssize_t length = 0; - PyObject *result; + PyObject *result, *it; result = PyList_New(0); if (result == NULL) @@ -665,14 +665,14 @@ _io__IOBase_readlines_impl(PyObject *self, Py_ssize_t hint) return result; } + it = PyObject_GetIter(self); + if (it == NULL) { + Py_DECREF(result); + return NULL; + } + while (1) { - PyObject *it, *line; - it = PyObject_GetIter(self); - if (it == NULL) { - Py_DECREF(result); - return NULL; - } - line = PyIter_Next(it); + PyObject *line = PyIter_Next(it); if (line == NULL) { if (PyErr_Occurred()) { Py_DECREF(result); From 39fdd22204a7172c20f39f6c4d7a0ff64a347a53 Mon Sep 17 00:00:00 2001 From: Xiang Zhang Date: Fri, 14 Apr 2017 16:20:04 +0800 Subject: [PATCH 4/4] fix reference leak --- Modules/_io/iobase.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c index b0b040eaf55d7d..968db9014b058c 100644 --- a/Modules/_io/iobase.c +++ b/Modules/_io/iobase.c @@ -643,7 +643,7 @@ _io__IOBase_readlines_impl(PyObject *self, Py_ssize_t hint) /*[clinic end generated code: output=2f50421677fa3dea input=9400c786ea9dc416]*/ { Py_ssize_t length = 0; - PyObject *result, *it; + PyObject *result, *it = NULL; result = PyList_New(0); if (result == NULL) @@ -658,8 +658,7 @@ _io__IOBase_readlines_impl(PyObject *self, Py_ssize_t hint) self, NULL); if (ret == NULL) { - Py_DECREF(result); - return NULL; + goto error; } Py_DECREF(ret); return result; @@ -667,16 +666,14 @@ _io__IOBase_readlines_impl(PyObject *self, Py_ssize_t hint) it = PyObject_GetIter(self); if (it == NULL) { - Py_DECREF(result); - return NULL; + goto error; } while (1) { PyObject *line = PyIter_Next(it); if (line == NULL) { if (PyErr_Occurred()) { - Py_DECREF(result); - return NULL; + goto error; } else break; /* StopIteration raised */ @@ -684,8 +681,7 @@ _io__IOBase_readlines_impl(PyObject *self, Py_ssize_t hint) if (PyList_Append(result, line) < 0) { Py_DECREF(line); - Py_DECREF(result); - return NULL; + goto error; } length += PyObject_Size(line); Py_DECREF(line); @@ -693,7 +689,12 @@ _io__IOBase_readlines_impl(PyObject *self, Py_ssize_t hint) if (length > hint) break; } + Py_DECREF(it); return result; + error: + Py_XDECREF(it); + Py_DECREF(result); + return NULL; } /*[clinic input]