Skip to content

Commit 097a664

Browse files
Issue #19687: Fixed possible integer overflows in ElementTree.
Based on patch by Christian Heimes.
1 parent d28bb62 commit 097a664

File tree

1 file changed

+34
-10
lines changed

1 file changed

+34
-10
lines changed

Modules/_elementtree.c

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -429,9 +429,9 @@ element_init(PyObject *self, PyObject *args, PyObject *kwds)
429429
}
430430

431431
LOCAL(int)
432-
element_resize(ElementObject* self, int extra)
432+
element_resize(ElementObject* self, Py_ssize_t extra)
433433
{
434-
int size;
434+
Py_ssize_t size;
435435
PyObject* *children;
436436

437437
/* make sure self->children can hold the given number of extra
@@ -453,6 +453,13 @@ element_resize(ElementObject* self, int extra)
453453
* be safe.
454454
*/
455455
size = size ? size : 1;
456+
if ((size_t)size > PY_SSIZE_T_MAX/sizeof(PyObject*))
457+
goto nomemory;
458+
if (size > INT_MAX) {
459+
PyErr_SetString(PyExc_OverflowError,
460+
"too many children");
461+
return -1;
462+
}
456463
if (self->extra->children != self->extra->_children) {
457464
/* Coverity CID #182 size_error: Allocating 1 bytes to pointer
458465
* "children", which needs at least 4 bytes. Although it's a
@@ -889,7 +896,7 @@ element_setstate_from_attributes(ElementObject *self,
889896
PyObject *tail,
890897
PyObject *children)
891898
{
892-
Py_ssize_t i, nchildren;
899+
int i, nchildren;
893900

894901
if (!tag) {
895902
PyErr_SetString(PyExc_TypeError, "tag may not be NULL");
@@ -914,11 +921,18 @@ element_setstate_from_attributes(ElementObject *self,
914921

915922
/* Compute 'nchildren'. */
916923
if (children) {
924+
Py_ssize_t size;
917925
if (!PyList_Check(children)) {
918926
PyErr_SetString(PyExc_TypeError, "'_children' is not a list");
919927
return NULL;
920928
}
921-
nchildren = PyList_Size(children);
929+
size = PyList_Size(children);
930+
/* expat limits nchildren to int */
931+
if (size > INT_MAX) {
932+
PyErr_SetString(PyExc_OverflowError, "too many children");
933+
return NULL;
934+
}
935+
nchildren = (int)size;
922936
}
923937
else {
924938
nchildren = 0;
@@ -1505,18 +1519,19 @@ element_set(ElementObject* self, PyObject* args)
15051519
}
15061520

15071521
static int
1508-
element_setitem(PyObject* self_, Py_ssize_t index, PyObject* item)
1522+
element_setitem(PyObject* self_, Py_ssize_t index_, PyObject* item)
15091523
{
15101524
ElementObject* self = (ElementObject*) self_;
1511-
int i;
1525+
int i, index;
15121526
PyObject* old;
15131527

1514-
if (!self->extra || index < 0 || index >= self->extra->length) {
1528+
if (!self->extra || index_ < 0 || index_ >= self->extra->length) {
15151529
PyErr_SetString(
15161530
PyExc_IndexError,
15171531
"child assignment index out of range");
15181532
return -1;
15191533
}
1534+
index = (int)index_;
15201535

15211536
old = self->extra->children[index];
15221537

@@ -1617,6 +1632,7 @@ element_ass_subscr(PyObject* self_, PyObject* item, PyObject* value)
16171632
&start, &stop, &step, &slicelen) < 0) {
16181633
return -1;
16191634
}
1635+
assert(slicelen <= self->extra->length);
16201636

16211637
if (value == NULL) {
16221638
/* Delete slice */
@@ -1678,7 +1694,7 @@ element_ass_subscr(PyObject* self_, PyObject* item, PyObject* value)
16781694
(self->extra->length - cur) * sizeof(PyObject *));
16791695
}
16801696

1681-
self->extra->length -= slicelen;
1697+
self->extra->length -= (int)slicelen;
16821698

16831699
/* Discard the recycle list with all the deleted sub-elements */
16841700
Py_XDECREF(recycle);
@@ -1714,6 +1730,8 @@ element_ass_subscr(PyObject* self_, PyObject* item, PyObject* value)
17141730
return -1;
17151731
}
17161732
}
1733+
assert(newlen - slicelen <= INT_MAX - self->extra->length);
1734+
assert(newlen - slicelen >= -self->extra->length);
17171735

17181736
if (slicelen > 0) {
17191737
/* to avoid recursive calls to this method (via decref), move
@@ -1747,7 +1765,7 @@ element_ass_subscr(PyObject* self_, PyObject* item, PyObject* value)
17471765
self->extra->children[cur] = element;
17481766
}
17491767

1750-
self->extra->length += newlen - slicelen;
1768+
self->extra->length += (int)(newlen - slicelen);
17511769

17521770
Py_DECREF(seq);
17531771

@@ -3528,8 +3546,14 @@ xmlparser_parse_whole(XMLParserObject* self, PyObject* args)
35283546
break;
35293547
}
35303548

3549+
if (PyBytes_GET_SIZE(buffer) > INT_MAX) {
3550+
Py_DECREF(buffer);
3551+
Py_DECREF(reader);
3552+
PyErr_SetString(PyExc_OverflowError, "size does not fit in an int");
3553+
return NULL;
3554+
}
35313555
res = expat_parse(
3532-
self, PyBytes_AS_STRING(buffer), PyBytes_GET_SIZE(buffer), 0
3556+
self, PyBytes_AS_STRING(buffer), (int)PyBytes_GET_SIZE(buffer), 0
35333557
);
35343558

35353559
Py_DECREF(buffer);

0 commit comments

Comments
 (0)