Skip to content

Commit 26861b0

Browse files
Issue #23450: Fixed possible integer overflows.
1 parent 4d0d982 commit 26861b0

File tree

8 files changed

+64
-50
lines changed

8 files changed

+64
-50
lines changed

Modules/_ctypes/_ctypes.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ _ctypes_alloc_format_string_with_shape(int ndim, const Py_ssize_t *shape,
301301
char *new_prefix;
302302
char *result;
303303
char buf[32];
304-
int prefix_len;
304+
Py_ssize_t prefix_len;
305305
int k;
306306

307307
prefix_len = 32 * ndim + 3;

Modules/_elementtree.c

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
*--------------------------------------------------------------------
1212
*/
1313

14+
#define PY_SSIZE_T_CLEAN
15+
1416
#include "Python.h"
1517
#include "structmember.h"
1618

@@ -185,8 +187,8 @@ typedef struct {
185187
PyObject* attrib;
186188

187189
/* child elements */
188-
int length; /* actual number of items */
189-
int allocated; /* allocated items */
190+
Py_ssize_t length; /* actual number of items */
191+
Py_ssize_t allocated; /* allocated items */
190192

191193
/* this either points to _children or to a malloced buffer */
192194
PyObject* *children;
@@ -251,7 +253,7 @@ LOCAL(void)
251253
dealloc_extra(ElementObject* self)
252254
{
253255
ElementObjectExtra *myextra;
254-
int i;
256+
Py_ssize_t i;
255257

256258
if (!self->extra)
257259
return;
@@ -429,9 +431,9 @@ element_init(PyObject *self, PyObject *args, PyObject *kwds)
429431
}
430432

431433
LOCAL(int)
432-
element_resize(ElementObject* self, int extra)
434+
element_resize(ElementObject* self, Py_ssize_t extra)
433435
{
434-
int size;
436+
Py_ssize_t size;
435437
PyObject* *children;
436438

437439
/* make sure self->children can hold the given number of extra
@@ -442,7 +444,7 @@ element_resize(ElementObject* self, int extra)
442444
return -1;
443445
}
444446

445-
size = self->extra->length + extra;
447+
size = self->extra->length + extra; /* never overflows */
446448

447449
if (size > self->extra->allocated) {
448450
/* use Python 2.4's list growth strategy */
@@ -453,6 +455,8 @@ element_resize(ElementObject* self, int extra)
453455
* be safe.
454456
*/
455457
size = size ? size : 1;
458+
if ((size_t)size > PY_SSIZE_T_MAX/sizeof(PyObject*))
459+
goto nomemory;
456460
if (self->extra->children != self->extra->_children) {
457461
/* Coverity CID #182 size_error: Allocating 1 bytes to pointer
458462
* "children", which needs at least 4 bytes. Although it's a
@@ -613,7 +617,7 @@ element_gc_traverse(ElementObject *self, visitproc visit, void *arg)
613617
Py_VISIT(JOIN_OBJ(self->tail));
614618

615619
if (self->extra) {
616-
int i;
620+
Py_ssize_t i;
617621
Py_VISIT(self->extra->attrib);
618622

619623
for (i = 0; i < self->extra->length; ++i)
@@ -689,7 +693,7 @@ element_clearmethod(ElementObject* self, PyObject* args)
689693
static PyObject*
690694
element_copy(ElementObject* self, PyObject* args)
691695
{
692-
int i;
696+
Py_ssize_t i;
693697
ElementObject* element;
694698

695699
if (!PyArg_ParseTuple(args, ":__copy__"))
@@ -728,7 +732,7 @@ element_copy(ElementObject* self, PyObject* args)
728732
static PyObject*
729733
element_deepcopy(ElementObject* self, PyObject* args)
730734
{
731-
int i;
735+
Py_ssize_t i;
732736
ElementObject* element;
733737
PyObject* tag;
734738
PyObject* attrib;
@@ -839,7 +843,7 @@ element_sizeof(PyObject* myself, PyObject* args)
839843
static PyObject *
840844
element_getstate(ElementObject *self)
841845
{
842-
int i, noattrib;
846+
Py_ssize_t i, noattrib;
843847
PyObject *instancedict = NULL, *children;
844848

845849
/* Build a list of children. */
@@ -1077,7 +1081,7 @@ element_extend(ElementObject* self, PyObject* args)
10771081
static PyObject*
10781082
element_find(ElementObject *self, PyObject *args, PyObject *kwds)
10791083
{
1080-
int i;
1084+
Py_ssize_t i;
10811085
PyObject* tag;
10821086
PyObject* namespaces = Py_None;
10831087
static char *kwlist[] = {"path", "namespaces", 0};
@@ -1112,7 +1116,7 @@ element_find(ElementObject *self, PyObject *args, PyObject *kwds)
11121116
static PyObject*
11131117
element_findtext(ElementObject *self, PyObject *args, PyObject *kwds)
11141118
{
1115-
int i;
1119+
Py_ssize_t i;
11161120
PyObject* tag;
11171121
PyObject* default_value = Py_None;
11181122
PyObject* namespaces = Py_None;
@@ -1153,7 +1157,7 @@ element_findtext(ElementObject *self, PyObject *args, PyObject *kwds)
11531157
static PyObject*
11541158
element_findall(ElementObject *self, PyObject *args, PyObject *kwds)
11551159
{
1156-
int i;
1160+
Py_ssize_t i;
11571161
PyObject* out;
11581162
PyObject* tag;
11591163
PyObject* namespaces = Py_None;
@@ -1238,7 +1242,7 @@ element_get(ElementObject* self, PyObject* args, PyObject* kwds)
12381242
static PyObject*
12391243
element_getchildren(ElementObject* self, PyObject* args)
12401244
{
1241-
int i;
1245+
Py_ssize_t i;
12421246
PyObject* list;
12431247

12441248
/* FIXME: report as deprecated? */
@@ -1310,11 +1314,9 @@ element_getitem(PyObject* self_, Py_ssize_t index)
13101314
static PyObject*
13111315
element_insert(ElementObject* self, PyObject* args)
13121316
{
1313-
int i;
1314-
1315-
int index;
1317+
Py_ssize_t index, i;
13161318
PyObject* element;
1317-
if (!PyArg_ParseTuple(args, "iO!:insert", &index,
1319+
if (!PyArg_ParseTuple(args, "nO!:insert", &index,
13181320
&Element_Type, &element))
13191321
return NULL;
13201322

@@ -1402,7 +1404,7 @@ element_makeelement(PyObject* self, PyObject* args, PyObject* kw)
14021404
static PyObject*
14031405
element_remove(ElementObject* self, PyObject* args)
14041406
{
1405-
int i;
1407+
Py_ssize_t i;
14061408

14071409
PyObject* element;
14081410
if (!PyArg_ParseTuple(args, "O!:remove", &Element_Type, &element))
@@ -1481,7 +1483,7 @@ static int
14811483
element_setitem(PyObject* self_, Py_ssize_t index, PyObject* item)
14821484
{
14831485
ElementObject* self = (ElementObject*) self_;
1484-
int i;
1486+
Py_ssize_t i;
14851487
PyObject* old;
14861488

14871489
if (!self->extra || index < 0 || index >= self->extra->length) {
@@ -2819,12 +2821,13 @@ makeuniversal(XMLParserObject* self, const char* string)
28192821
* message string is the default for the given error_code.
28202822
*/
28212823
static void
2822-
expat_set_error(enum XML_Error error_code, int line, int column, char *message)
2824+
expat_set_error(enum XML_Error error_code, Py_ssize_t line, Py_ssize_t column,
2825+
const char *message)
28232826
{
28242827
PyObject *errmsg, *error, *position, *code;
28252828
elementtreestate *st = ET_STATE_GLOBAL;
28262829

2827-
errmsg = PyUnicode_FromFormat("%s: line %d, column %d",
2830+
errmsg = PyUnicode_FromFormat("%s: line %zd, column %zd",
28282831
message ? message : EXPAT(ErrorString)(error_code),
28292832
line, column);
28302833
if (errmsg == NULL)
@@ -2848,7 +2851,7 @@ expat_set_error(enum XML_Error error_code, int line, int column, char *message)
28482851
}
28492852
Py_DECREF(code);
28502853

2851-
position = Py_BuildValue("(ii)", line, column);
2854+
position = Py_BuildValue("(nn)", line, column);
28522855
if (!position) {
28532856
Py_DECREF(error);
28542857
return;
@@ -3477,8 +3480,14 @@ xmlparser_parse_whole(XMLParserObject* self, PyObject* args)
34773480
break;
34783481
}
34793482

3483+
if (PyBytes_GET_SIZE(buffer) > INT_MAX) {
3484+
Py_DECREF(buffer);
3485+
Py_DECREF(reader);
3486+
PyErr_SetString(PyExc_OverflowError, "size does not fit in an int");
3487+
return NULL;
3488+
}
34803489
res = expat_parse(
3481-
self, PyBytes_AS_STRING(buffer), PyBytes_GET_SIZE(buffer), 0
3490+
self, PyBytes_AS_STRING(buffer), (int)PyBytes_GET_SIZE(buffer), 0
34823491
);
34833492

34843493
Py_DECREF(buffer);

Modules/_sqlite/row.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ Py_ssize_t pysqlite_row_length(pysqlite_Row* self, PyObject* args, PyObject* kwa
159159
PyObject* pysqlite_row_keys(pysqlite_Row* self, PyObject* args, PyObject* kwargs)
160160
{
161161
PyObject* list;
162-
int nitems, i;
162+
Py_ssize_t nitems, i;
163163

164164
list = PyList_New(0);
165165
if (!list) {

Modules/_tkinter.c

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Copyright (C) 1994 Steen Lumholt.
2121
2222
*/
2323

24+
#define PY_SSIZE_T_CLEAN
2425

2526
#include "Python.h"
2627
#include <ctype.h>
@@ -34,7 +35,7 @@ Copyright (C) 1994 Steen Lumholt.
3435
#endif
3536

3637
#define CHECK_SIZE(size, elemsize) \
37-
((size_t)(size) <= Py_MAX((size_t)INT_MAX, UINT_MAX / (size_t)(elemsize)))
38+
((size_t)(size) <= Py_MIN((size_t)INT_MAX, UINT_MAX / (size_t)(elemsize)))
3839

3940
/* If Tcl is compiled for threads, we must also define TCL_THREAD. We define
4041
it always; if Tcl is not threaded, the thread functions in
@@ -409,7 +410,7 @@ static PyObject *
409410
SplitObj(PyObject *arg)
410411
{
411412
if (PyTuple_Check(arg)) {
412-
int i, size;
413+
Py_ssize_t i, size;
413414
PyObject *elem, *newelem, *result;
414415

415416
size = PyTuple_Size(arg);
@@ -425,7 +426,7 @@ SplitObj(PyObject *arg)
425426
return NULL;
426427
}
427428
if (!result) {
428-
int k;
429+
Py_ssize_t k;
429430
if (newelem == elem) {
430431
Py_DECREF(newelem);
431432
continue;
@@ -446,7 +447,7 @@ SplitObj(PyObject *arg)
446447
/* Fall through, returning arg. */
447448
}
448449
else if (PyList_Check(arg)) {
449-
int i, size;
450+
Py_ssize_t i, size;
450451
PyObject *elem, *newelem, *result;
451452

452453
size = PyList_GET_SIZE(arg);
@@ -632,12 +633,12 @@ Tkapp_New(const char *screenName, const char *className,
632633
/* some initial arguments need to be in argv */
633634
if (sync || use) {
634635
char *args;
635-
int len = 0;
636+
Py_ssize_t len = 0;
636637

637638
if (sync)
638639
len += sizeof "-sync";
639640
if (use)
640-
len += strlen(use) + sizeof "-use ";
641+
len += strlen(use) + sizeof "-use "; /* never overflows */
641642

642643
args = (char*)PyMem_Malloc(len);
643644
if (!args) {
@@ -887,9 +888,14 @@ AsObj(PyObject *value)
887888
long longVal;
888889
int overflow;
889890

890-
if (PyBytes_Check(value))
891+
if (PyBytes_Check(value)) {
892+
if (PyBytes_GET_SIZE(value) >= INT_MAX) {
893+
PyErr_SetString(PyExc_OverflowError, "bytes object is too long");
894+
return NULL;
895+
}
891896
return Tcl_NewByteArrayObj((unsigned char *)PyBytes_AS_STRING(value),
892-
PyBytes_GET_SIZE(value));
897+
(int)PyBytes_GET_SIZE(value));
898+
}
893899
else if (PyBool_Check(value))
894900
return Tcl_NewBooleanObj(PyObject_IsTrue(value));
895901
else if (PyLong_CheckExact(value) &&
@@ -921,7 +927,7 @@ AsObj(PyObject *value)
921927
}
922928
for (i = 0; i < size; i++)
923929
argv[i] = AsObj(PySequence_Fast_GET_ITEM(value,i));
924-
result = Tcl_NewListObj(size, argv);
930+
result = Tcl_NewListObj((int)size, argv);
925931
PyMem_Free(argv);
926932
return result;
927933
}
@@ -946,7 +952,7 @@ AsObj(PyObject *value)
946952
}
947953
kind = PyUnicode_KIND(value);
948954
if (kind == sizeof(Tcl_UniChar))
949-
return Tcl_NewUnicodeObj(inbuf, size);
955+
return Tcl_NewUnicodeObj(inbuf, (int)size);
950956
allocsize = ((size_t)size) * sizeof(Tcl_UniChar);
951957
outbuf = (Tcl_UniChar*)PyMem_Malloc(allocsize);
952958
/* Else overflow occurred, and we take the next exit */
@@ -971,7 +977,7 @@ AsObj(PyObject *value)
971977
#endif
972978
outbuf[i] = ch;
973979
}
974-
result = Tcl_NewUnicodeObj(outbuf, size);
980+
result = Tcl_NewUnicodeObj(outbuf, (int)size);
975981
PyMem_Free(outbuf);
976982
return result;
977983
}
@@ -1139,10 +1145,10 @@ Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc)
11391145
Tcl_IncrRefCount(objv[i]);
11401146
}
11411147
}
1142-
*pobjc = objc;
1148+
*pobjc = (int)objc;
11431149
return objv;
11441150
finally:
1145-
Tkapp_CallDeallocArgs(objv, objStore, objc);
1151+
Tkapp_CallDeallocArgs(objv, objStore, (int)objc);
11461152
return NULL;
11471153
}
11481154

@@ -1495,7 +1501,6 @@ var_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags)
14951501
#ifdef WITH_THREAD
14961502
TkappObject *self = (TkappObject*)selfptr;
14971503
if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
1498-
TkappObject *self = (TkappObject*)selfptr;
14991504
VarEvent *ev;
15001505
PyObject *res, *exc_type, *exc_val;
15011506
Tcl_Condition cond = NULL;
@@ -2721,20 +2726,20 @@ static PyType_Spec Tkapp_Type_spec = {
27212726

27222727
typedef struct {
27232728
PyObject* tuple;
2724-
int size; /* current size */
2725-
int maxsize; /* allocated size */
2729+
Py_ssize_t size; /* current size */
2730+
Py_ssize_t maxsize; /* allocated size */
27262731
} FlattenContext;
27272732

27282733
static int
2729-
_bump(FlattenContext* context, int size)
2734+
_bump(FlattenContext* context, Py_ssize_t size)
27302735
{
27312736
/* expand tuple to hold (at least) size new items.
27322737
return true if successful, false if an exception was raised */
27332738

2734-
int maxsize = context->maxsize * 2;
2739+
Py_ssize_t maxsize = context->maxsize * 2; /* never overflows */
27352740

27362741
if (maxsize < context->size + size)
2737-
maxsize = context->size + size;
2742+
maxsize = context->size + size; /* never overflows */
27382743

27392744
context->maxsize = maxsize;
27402745

@@ -2746,7 +2751,7 @@ _flatten1(FlattenContext* context, PyObject* item, int depth)
27462751
{
27472752
/* add tuple or list to argument tuple (recursively) */
27482753

2749-
int i, size;
2754+
Py_ssize_t i, size;
27502755

27512756
if (depth > 1000) {
27522757
PyErr_SetString(PyExc_ValueError,

Objects/bytesobject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -673,7 +673,7 @@ _PyBytes_Format(PyObject *format, PyObject *args)
673673
"* wants int");
674674
goto error;
675675
}
676-
prec = PyLong_AsSsize_t(v);
676+
prec = _PyLong_AsInt(v);
677677
if (prec == -1 && PyErr_Occurred())
678678
goto error;
679679
if (prec < 0)

Objects/obmalloc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1339,7 +1339,7 @@ _PyObject_Alloc(int use_calloc, void *ctx, size_t nelem, size_t elsize)
13391339
pool = (poolp)usable_arenas->pool_address;
13401340
assert((block*)pool <= (block*)usable_arenas->address +
13411341
ARENA_SIZE - POOL_SIZE);
1342-
pool->arenaindex = usable_arenas - arenas;
1342+
pool->arenaindex = (uint)(usable_arenas - arenas);
13431343
assert(&arenas[pool->arenaindex] == usable_arenas);
13441344
pool->szidx = DUMMY_SIZE_IDX;
13451345
usable_arenas->pool_address += POOL_SIZE;

0 commit comments

Comments
 (0)