8000 [2.7] bpo-30061: Check if PyObject_Size()/PySequence_Size()/PyMapping… · python/cpython@64aa4df · GitHub
[go: up one dir, main page]

Skip to content

Commit 64aa4df

Browse files
[2.7] bpo-30061: Check if PyObject_Size()/PySequence_Size()/PyMapping_Size() (GH-1096) (GH-1180) (#1183)
raised an error. (cherry picked from commit bf623ae) (cherry picked from commit 680fea4)
1 parent 32c43fb commit 64aa4df

File tree

5 files changed

+37
-5
lines changed

5 files changed

+37
-5
lines changed

Lib/test/test_io.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,22 @@ def test_readline(self):
396396
with self.open(support.TESTFN, "r") as f:
397397
self.assertRaises(TypeError, f.readline, 5.3)
398398

399+
def test_readline_nonsizeable(self):
400+
# Issue #30061
401+
# Crash when readline() returns an object without __len__
402+
class R(self.IOBase):
403+
def readline(self):
404+
return None
405+
self.assertRaises((TypeError, StopIteration), next, R())
406+
407+
def test_next_nonsizeable(self):
408+
# Issue #30061
409+
# Crash when next() returns an object without __len__
410+
class R(self.IOBase):
411+
def next(self):
412+
return None
413+
self.assertRaises(TypeError, R().readlines, 1)
414+
399415
def test_raw_bytes_io(self):
400416
f = self.BytesIO()
401417
self.write_ops(f)

Misc/NEWS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ Extension Modules
4242
Library
4343
-------
4444

45+
- bpo-30061: Fixed crashes in IOBase methods next() and readlines() when
46+
readline() or next() respectively return non-sizeable object.
47+
Fixed possible other errors caused by not checking results of PyObject_Size(),
48+
PySequence_Size(), or PyMapping_Size().
49+
4550
- bpo-30011: Fixed race condition in HTMLParser.unescape().
4651

4752
- bpo-30068: _io._IOBase.readlines will check if it's closed first when

Modules/_io/iobase.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,8 @@ iobase_iternext(PyObject *self)
571571
if (line == NULL)
572572
return NULL;
573573

574-
if (PyObject_Size(line) == 0) {
574+
if (PyObject_Size(line) <= 0) {
575+
/* Error or empty */
575576
Py_DECREF(line);
576577
return NULL;
577578
}
@@ -618,6 +619,7 @@ iobase_readlines(PyObject *self, PyObject *args)
618619
}
619620

620621
while (1) {
622+
Py_ssize_t line_length;
621623
PyObject *line = PyIter_Next(it);
622624
if (line == NULL) {
623625
if (PyErr_Occurred()) {
@@ -631,11 +633,14 @@ iobase_readlines(PyObject *self, PyObject *args)
631633
Py_DECREF(line);
632634
goto error;
633635
}
634-
length += PyObject_Size(line);
636+
line_length = PyObject_Size(line);
635637
Py_DECREF(line);
636-
637-
if (length > hint)
638+
if (line_length < 0) {
639+
goto error;
640+
}
641+
if (line_length > hint - length)
638642
break;
643+
length += line_length;
639644
}
640645

641646
Py_DECREF(it);

Modules/cjkcodecs/multibytecodec.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1604,6 +1604,9 @@ mbstreamwriter_writelines(MultibyteStreamWriterObject *self, PyObject *lines)
16041604
if (r == -1)
16051605
return NULL;
16061606
}
1607+
/* PySequence_Length() can fail */
1608+
if (PyErr_Occurred())
1609+
return NULL;
16071610

16081611
Py_RETURN_NONE;
16091612
}

Modules/posixmodule.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6077,14 +6077,17 @@ Set the groups of the current process to list.");
60776077
static PyObject *
60786078
posix_setgroups(PyObject *self, PyObject *groups)
60796079
{
6080-
int i, len;
6080+
Py_ssize_t i, len;
60816081
gid_t grouplist[MAX_GROUPS];
60826082

60836083
if (!PySequence_Check(groups)) {
60846084
PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
60856085
return NULL;
60866086
}
60876087
len = PySequence_Size(groups);
6088+
if (len < 0) {
6089+
return NULL;
6090+
}
60886091
if (len > MAX_GROUPS) {
60896092
PyErr_SetString(PyExc_ValueError, "too many groups");
60906093
return NULL;

0 commit comments

Comments
 (0)
0