[Python-checkins] cpython (2.7): Issue #19687: Fixed possible integer overflows in ElementTree.

serhiy.storchaka python-checkins at python.org
Wed Nov 25 13:18:41 EST 2015


https://hg.python.org/cpython/rev/745fd5550bc0
changeset:   99361:745fd5550bc0
branch:      2.7
parent:      99359:4a201d0d4d1e
user:        Serhiy Storchaka <storchaka at gmail.com>
date:        Wed Nov 25 20:12:58 2015 +0200
summary:
  Issue #19687: Fixed possible integer overflows in ElementTree.
Based on patch by Christian Heimes.

files:
  Modules/_elementtree.c |  29 +++++++++++++++++++++++------
  1 files changed, 23 insertions(+), 6 deletions(-)


diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c
--- a/Modules/_elementtree.c
+++ b/Modules/_elementtree.c
@@ -337,9 +337,9 @@
 }
 
 LOCAL(int)
-element_resize(ElementObject* self, int extra)
+element_resize(ElementObject* self, Py_ssize_t extra)
 {
-    int size;
+    Py_ssize_t size;
     PyObject* *children;
 
     /* make sure self->children can hold the given number of extra
@@ -359,6 +359,13 @@
          * be safe.
          */
         size = size ? size : 1;
+        if ((size_t)size > PY_SSIZE_T_MAX/sizeof(PyObject*))
+            goto nomemory;
+        if (size > INT_MAX) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "too many children");
+            return -1;
+        }
         if (self->extra->children != self->extra->_children) {
             /* Coverity CID #182 size_error: Allocating 1 bytes to pointer
              * "children", which needs at least 4 bytes. Although it's a 
@@ -1256,15 +1263,16 @@
 element_setitem(PyObject* self_, Py_ssize_t index, PyObject* item)
 {
     ElementObject* self = (ElementObject*) self_;
-    int i;
+    int i, index;
     PyObject* old;
 
-    if (!self->extra || index < 0 || index >= self->extra->length) {
+    if (!self->extra || index_ < 0 || index_ >= self->extra->length) {
         PyErr_SetString(
             PyExc_IndexError,
             "child assignment index out of range");
         return -1;
     }
+    index = (int)index_;
 
     old = self->extra->children[index];
 
@@ -1373,6 +1381,7 @@
                 &start, &stop, &step, &slicelen) < 0) {
             return -1;
         }
+        assert(slicelen <= self->extra->length);
 
         if (value == NULL)
             newlen = 0;
@@ -1413,6 +1422,8 @@
                 return -1;
             }
         }
+        assert(newlen - slicelen <= INT_MAX - self->extra->length);
+        assert(newlen - slicelen >= -self->extra->length);
 
         if (slicelen > 0) {
             /* to avoid recursive calls to this method (via decref), move
@@ -1446,7 +1457,7 @@
             self->extra->children[cur] = element;
         }
 
-        self->extra->length += newlen - slicelen;
+        self->extra->length += (int)(newlen - slicelen);
 
         Py_XDECREF(seq);
 
@@ -2704,8 +2715,14 @@
             break;
         }
 
+        if (PyString_GET_SIZE(buffer) > INT_MAX) {
+            Py_DECREF(buffer);
+            Py_DECREF(reader);
+            PyErr_SetString(PyExc_OverflowError, "size does not fit in an int");
+            return NULL;
+        }
         res = expat_parse(
-            self, PyString_AS_STRING(buffer), PyString_GET_SIZE(buffer), 0
+            self, PyString_AS_STRING(buffer), (int)PyString_GET_SIZE(buffer), 0
             );
 
         Py_DECREF(buffer);

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list