Skip to content

Commit 5fbdfc3

Browse files
authored
bpo-30068: add missing iter(self) in _io._IOBase.readlines when hint is present (#1152)
1 parent 0b46fcf commit 5fbdfc3

File tree

3 files changed

+25
-13
lines changed

3 files changed

+25
-13
lines changed

‎Lib/test/test_io.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2933,6 +2933,7 @@ def test_io_after_close(self):
29332933
self.assertRaises(ValueError, f.readinto, bytearray(1024))
29342934
self.assertRaises(ValueError, f.readline)
29352935
self.assertRaises(ValueError, f.readlines)
2936+
self.assertRaises(ValueError, f.readlines, 1)
29362937
self.assertRaises(ValueError, f.seek, 0)
29372938
self.assertRaises(ValueError, f.tell)
29382939
self.assertRaises(ValueError, f.truncate)

‎Misc/NEWS‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ Extension Modules
4242
Library
4343
-------
4444

45+
- bpo-30068: _io._IOBase.readlines will check if it's closed first when
46+
hint is present.
47+
4548
- bpo-27863: Fixed multiple crashes in ElementTree caused by race conditions
4649
and wrong types.
4750

@@ -12349,4 +12352,3 @@ Mac
1234912352
----
1235012353

1235112354
**(For information about older versions, consult the HISTORY file.)**
12352-

‎Modules/_io/iobase.c‎

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
/*
22
An implementation of the I/O abstract base classes hierarchy
33
as defined by PEP 3116 - "New I/O"
4-
4+
55
Classes defined here: IOBase, RawIOBase.
6-
6+
77
Written by Amaury Forgeot d'Arc and Antoine Pitrou
88
*/
99

@@ -19,7 +19,7 @@
1919

2020
typedef struct {
2121
PyObject_HEAD
22-
22+
2323
PyObject *dict;
2424
PyObject *weakreflist;
2525
} iobase;
@@ -590,7 +590,7 @@ static PyObject *
590590
iobase_readlines(PyObject *self, PyObject *args)
591591
{
592592
Py_ssize_t hint = -1, length = 0;
593-
PyObject *result;
593+
PyObject *result, *it = NULL;
594594

595595
if (!PyArg_ParseTuple(args, "|O&:readlines", &_PyIO_ConvertSsize_t, &hint)) {
596596
return NULL;
@@ -606,36 +606,45 @@ iobase_readlines(PyObject *self, PyObject *args)
606606
probably be removed here. */
607607
PyObject *ret = PyObject_CallMethod(result, "extend", "O", self);
608608
if (ret == NULL) {
609-
Py_DECREF(result);
610-
return NULL;
609+
goto error;
611610
}
612611
Py_DECREF(ret);
613612
return result;
614613
}
615614

615+
it = PyObject_GetIter(self);
616+
if (it == NULL) {
617+
goto error;
618+
}
619+
616620
while (1) {
617-
PyObject *line = PyIter_Next(self);
621+
PyObject *line = PyIter_Next(it);
618622
if (line == NULL) {
619623
if (PyErr_Occurred()) {
620-
Py_DECREF(result);
621-
return NULL;
624+
goto error;
622625
}
623626
else
624627
break; /* StopIteration raised */
625628
}
626629

627630
if (PyList_Append(result, line) < 0) {
628631
Py_DECREF(line);
629-
Py_DECREF(result);
630-
return NULL;
632+
goto error;
631633
}
632634
length += PyObject_Size(line);
633635
Py_DECREF(line);
634636

635637
if (length > hint)
636638
break;
637639
}
640+
641+
Py_DECREF(it);
638642
return result;
643+
644+
error:
645+
Py_XDECREF(it);
646+
Py_DECREF(result);
647+
return NULL;
639648
}
640649

641650
static PyObject *
@@ -823,7 +832,7 @@ rawiobase_readall(PyObject *self, PyObject *args)
823832
int r;
824833
PyObject *chunks = PyList_New(0);
825834
PyObject *result;
826-
835+
827836
if (chunks == NULL)
828837
return NULL;
829838

0 commit comments

Comments
 (0)