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

raised an error.

(cherry picked from commit bf623ae8843dc30b28c574bec8d29fc14be59d86)
(cherry picked from commit 680fea4)
diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py
index fb91a2d..caca033 100644
--- a/Lib/test/test_io.py
+++ b/Lib/test/test_io.py
@@ -396,6 +396,22 @@
         with self.open(support.TESTFN, "r") as f:
             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):
         f = self.BytesIO()
         self.write_ops(f)
diff --git a/Misc/NEWS b/Misc/NEWS
index f2bd997..29c5e98 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -42,6 +42,11 @@
 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-30068: _io._IOBase.readlines will check if it's closed first when
diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c
index 066dc8e..d813daf 100644
--- a/Modules/_io/iobase.c
+++ b/Modules/_io/iobase.c
@@ -571,7 +571,8 @@
     if (line == NULL)
         return NULL;
 
-    if (PyObject_Size(line) == 0) {
+    if (PyObject_Size(line) <= 0) {
+        /* Error or empty */
         Py_DECREF(line);
         return NULL;
     }
@@ -618,6 +619,7 @@
     }
 
     while (1) {
+        Py_ssize_t line_length;
         PyObject *line = PyIter_Next(it);
         if (line == NULL) {
             if (PyErr_Occurred()) {
@@ -631,11 +633,14 @@
             Py_DECREF(line);
             goto error;
         }
-        length += PyObject_Size(line);
+        line_length = PyObject_Size(line);
         Py_DECREF(line);
-
-        if (length > hint)
+        if (line_length < 0) {
+            goto error;
+        }
+        if (line_length > hint - length)
             break;
+        length += line_length;
     }
 
     Py_DECREF(it);
diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c
index 8713628..8901b42 100644
--- a/Modules/cjkcodecs/multibytecodec.c
+++ b/Modules/cjkcodecs/multibytecodec.c
@@ -1604,6 +1604,9 @@
         if (r == -1)
             return NULL;
     }
+    /* PySequence_Length() can fail */
+    if (PyErr_Occurred())
+        return NULL;
 
     Py_RETURN_NONE;
 }
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index e73805f..ad50536 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -6077,7 +6077,7 @@
 static PyObject *
 posix_setgroups(PyObject *self, PyObject *groups)
 {
-    int i, len;
+    Py_ssize_t i, len;
     gid_t grouplist[MAX_GROUPS];
 
     if (!PySequence_Check(groups)) {
@@ -6085,6 +6085,9 @@
         return NULL;
     }
     len = PySequence_Size(groups);
+    if (len < 0) {
+        return NULL;
+    }
     if (len > MAX_GROUPS) {
         PyErr_SetString(PyExc_ValueError, "too many groups");
         return NULL;