summaryrefslogtreecommitdiff
path: root/Modules/_tkinter.c
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2013-08-21 21:43:08 +0300
committerSerhiy Storchaka <storchaka@gmail.com>2013-08-21 21:43:08 +0300
commit4e4088d2734e9f53b4947b8fc1024c4884d26c5e (patch)
treeef00bfb0a0876b1ab2f87ebf2ff8b6de283048f8 /Modules/_tkinter.c
parent6acbe2aaa385ada342ac9421333fce083041f06f (diff)
parent9e6b97502f3a0c5f7d24e0b7f05dc9b41b0d0b85 (diff)
downloadcpython-git-4e4088d2734e9f53b4947b8fc1024c4884d26c5e.tar.gz
Issue #17119: Fixed integer overflows when processing large strings and tuples
in the tkinter module.
Diffstat (limited to 'Modules/_tkinter.c')
-rw-r--r--Modules/_tkinter.c29
1 files changed, 23 insertions, 6 deletions
diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c
index 637a9bb205..c6f63ac888 100644
--- a/Modules/_tkinter.c
+++ b/Modules/_tkinter.c
@@ -47,6 +47,9 @@ Copyright (C) 1994 Steen Lumholt.
#define PyBool_FromLong PyLong_FromLong
#endif
+#define CHECK_SIZE(size, elemsize) \
+ ((size_t)(size) <= Py_MAX((size_t)INT_MAX, UINT_MAX / (size_t)(elemsize)))
+
/* Starting with Tcl 8.4, many APIs offer const-correctness. Unfortunately,
making _tkinter correct for this API means to break earlier
versions. USE_COMPAT_CONST allows to make _tkinter work with both 8.4 and
@@ -850,12 +853,18 @@ AsObj(PyObject *value)
else if (PyFloat_Check(value))
return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
else if (PyTuple_Check(value)) {
- Tcl_Obj **argv = (Tcl_Obj**)
- ckalloc(PyTuple_Size(value)*sizeof(Tcl_Obj*));
- int i;
+ Tcl_Obj **argv;
+ Py_ssize_t size, i;
+
+ size = PyTuple_Size(value);
+ if (!CHECK_SIZE(size, sizeof(Tcl_Obj *))) {
+ PyErr_SetString(PyExc_OverflowError, "tuple is too long");
+ return NULL;
+ }
+ argv = (Tcl_Obj **) ckalloc(((size_t)size) * sizeof(Tcl_Obj *));
if(!argv)
return 0;
- for(i=0;i<PyTuple_Size(value);i++)
+ for (i = 0; i < size; i++)
argv[i] = AsObj(PyTuple_GetItem(value,i));
result = Tcl_NewListObj(PyTuple_Size(value), argv);
ckfree(FREECAST argv);
@@ -874,6 +883,10 @@ AsObj(PyObject *value)
inbuf = PyUnicode_DATA(value);
size = PyUnicode_GET_LENGTH(value);
+ if (!CHECK_SIZE(size, sizeof(Tcl_UniChar))) {
+ PyErr_SetString(PyExc_OverflowError, "string is too long");
+ return NULL;
+ }
kind = PyUnicode_KIND(value);
allocsize = ((size_t)size) * sizeof(Tcl_UniChar);
outbuf = (Tcl_UniChar*)ckalloc(allocsize);
@@ -1029,7 +1042,7 @@ static Tcl_Obj**
Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc)
{
Tcl_Obj **objv = objStore;
- int objc = 0, i;
+ Py_ssize_t objc = 0, i;
if (args == NULL)
/* do nothing */;
@@ -1044,7 +1057,11 @@ Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc)
objc = PyTuple_Size(args);
if (objc > ARGSZ) {
- objv = (Tcl_Obj **)ckalloc(objc * sizeof(char *));
+ if (!CHECK_SIZE(objc, sizeof(Tcl_Obj *))) {
+ PyErr_SetString(PyExc_OverflowError, "tuple is too long");
+ return NULL;
+ }
+ objv = (Tcl_Obj **)ckalloc(((size_t)objc) * sizeof(Tcl_Obj *));
if (objv == NULL) {
PyErr_NoMemory();
objc = 0;