Commit 64aa4df8 authored by Serhiy Storchaka's avatar Serhiy Storchaka Committed by GitHub

[2.7] bpo-30061: Check if PyObject_Size()/PySequence_Size()/PyMapping_Size()...

[2.7] bpo-30061: Check if PyObject_Size()/PySequence_Size()/PyMapping_Size() (GH-1096) (GH-1180) (#1183)

raised an error.

(cherry picked from commit bf623ae8)
(cherry picked from commit 680fea4)
parent 32c43fbf
...@@ -396,6 +396,22 @@ class IOTest(unittest.TestCase): ...@@ -396,6 +396,22 @@ class IOTest(unittest.TestCase):
with self.open(support.TESTFN, "r") as f: with self.open(support.TESTFN, "r") as f:
self.assertRaises(TypeError, f.readline, 5.3) self.assertRaises(TypeError, f.readline, 5.3)
def test_readline_nonsizeable(self):
# Issue #30061
# Crash when readline() returns an object without __len__
class R(self.IOBase):
def readline(self):
return None
self.assertRaises((TypeError, StopIteration), next, R())
def test_next_nonsizeable(self):
# Issue #30061
# Crash when next() returns an object without __len__
class R(self.IOBase):
def next(self):
return None
self.assertRaises(TypeError, R().readlines, 1)
def test_raw_bytes_io(self): def test_raw_bytes_io(self):
f = self.BytesIO() f = self.BytesIO()
self.write_ops(f) self.write_ops(f)
......
...@@ -42,6 +42,11 @@ Extension Modules ...@@ -42,6 +42,11 @@ Extension Modules
Library Library
------- -------
- bpo-30061: Fixed crashes in IOBase methods next() and readlines() when
readline() or next() respectively return non-sizeable object.
Fixed possible other errors caused by not checking results of PyObject_Size(),
PySequence_Size(), or PyMapping_Size().
- bpo-30011: Fixed race condition in HTMLParser.unescape(). - bpo-30011: Fixed race condition in HTMLParser.unescape().
- bpo-30068: _io._IOBase.readlines will check if it's closed first when - bpo-30068: _io._IOBase.readlines will check if it's closed first when
......
...@@ -571,7 +571,8 @@ iobase_iternext(PyObject *self) ...@@ -571,7 +571,8 @@ iobase_iternext(PyObject *self)
if (line == NULL) if (line == NULL)
return NULL; return NULL;
if (PyObject_Size(line) == 0) { if (PyObject_Size(line) <= 0) {
/* Error or empty */
Py_DECREF(line); Py_DECREF(line);
return NULL; return NULL;
} }
...@@ -618,6 +619,7 @@ iobase_readlines(PyObject *self, PyObject *args) ...@@ -618,6 +619,7 @@ iobase_readlines(PyObject *self, PyObject *args)
} }
while (1) { while (1) {
Py_ssize_t line_length;
PyObject *line = PyIter_Next(it); PyObject *line = PyIter_Next(it);
if (line == NULL) { if (line == NULL) {
if (PyErr_Occurred()) { if (PyErr_Occurred()) {
...@@ -631,11 +633,14 @@ iobase_readlines(PyObject *self, PyObject *args) ...@@ -631,11 +633,14 @@ iobase_readlines(PyObject *self, PyObject *args)
Py_DECREF(line); Py_DECREF(line);
goto error; goto error;
} }
length += PyObject_Size(line); line_length = PyObject_Size(line);
Py_DECREF(line); Py_DECREF(line);
if (line_length < 0) {
if (length > hint) goto error;
}
if (line_length > hint - length)
break; break;
length += line_length;
} }
Py_DECREF(it); Py_DECREF(it);
......
...@@ -1604,6 +1604,9 @@ mbstreamwriter_writelines(MultibyteStreamWriterObject *self, PyObject *lines) ...@@ -1604,6 +1604,9 @@ mbstreamwriter_writelines(MultibyteStreamWriterObject *self, PyObject *lines)
if (r == -1) if (r == -1)
return NULL; return NULL;
} }
/* PySequence_Length() can fail */
if (PyErr_Occurred())
return NULL;
Py_RETURN_NONE; Py_RETURN_NONE;
} }
......
...@@ -6077,7 +6077,7 @@ Set the groups of the current process to list."); ...@@ -6077,7 +6077,7 @@ Set the groups of the current process to list.");
static PyObject * static PyObject *
posix_setgroups(PyObject *self, PyObject *groups) posix_setgroups(PyObject *self, PyObject *groups)
{ {
int i, len; Py_ssize_t i, len;
gid_t grouplist[MAX_GROUPS]; gid_t grouplist[MAX_GROUPS];
if (!PySequence_Check(groups)) { if (!PySequence_Check(groups)) {
...@@ -6085,6 +6085,9 @@ posix_setgroups(PyObject *self, PyObject *groups) ...@@ -6085,6 +6085,9 @@ posix_setgroups(PyObject *self, PyObject *groups)
return NULL; return NULL;
} }
len = PySequence_Size(groups); len = PySequence_Size(groups);
if (len < 0) {
return NULL;
}
if (len > MAX_GROUPS) { if (len > MAX_GROUPS) {
PyErr_SetString(PyExc_ValueError, "too many groups"); PyErr_SetString(PyExc_ValueError, "too many groups");
return NULL; return NULL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment