From c4c64be1b81c3d59ec0429663ed53d8f11c9b38a Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 25 Nov 2015 20:12:58 +0200 Subject: [PATCH] Issue #19687: Fixed possible integer overflows in ElementTree. Based on patch by Christian Heimes. --- Modules/_elementtree.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index 48bf7800c64..62b7edec0c3 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -337,9 +337,9 @@ element_new(PyObject* tag, PyObject* attrib) } 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 @@ element_resize(ElementObject* self, int extra) * 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 @@ static int 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 @@ element_ass_subscr(PyObject* self_, PyObject* item, PyObject* value) &start, &stop, &step, &slicelen) < 0) { return -1; } + assert(slicelen <= self->extra->length); if (value == NULL) newlen = 0; @@ -1413,6 +1422,8 @@ element_ass_subscr(PyObject* self_, PyObject* item, PyObject* value) 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 @@ element_ass_subscr(PyObject* self_, PyObject* item, PyObject* value) self->extra->children[cur] = element; } - self->extra->length += newlen - slicelen; + self->extra->length += (int)(newlen - slicelen); Py_XDECREF(seq); @@ -2704,8 +2715,14 @@ xmlparser_parse(XMLParserObject* self, PyObject* args) 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);