diff -r 4a6b8f86b081 Lib/test/test_tcl.py --- a/Lib/test/test_tcl.py Mon Apr 15 23:14:55 2013 -0700 +++ b/Lib/test/test_tcl.py Tue Apr 16 10:06:44 2013 +0300 @@ -3,6 +3,7 @@ import unittest import sys import os +import _testcapi from test import support # Skip this test if the _tkinter module wasn't built. @@ -176,8 +177,21 @@ self.assertEqual(passValue((1, '2', (3.4,))), (1, '2', (3.4,))) +class BigmemTclTest(unittest.TestCase): + + def setUp(self): + self.interp = Tcl() + + @unittest.skipUnless(_testcapi.INT_MAX < _testcapi.PY_SSIZE_T_MAX, + "needs UINT_MAX < SIZE_MAX") + @support.bigmemtest(size=_testcapi.INT_MAX + 1, memuse=5, dry_run=False) + def test_huge_string(self, size): + value = ' ' * size + self.assertRaises(OverflowError, self.interp.call, 'set', '_', value) + + def test_main(): - support.run_unittest(TclTest, TkinterTest) + support.run_unittest(TclTest, TkinterTest, BigmemTclTest) if __name__ == "__main__": test_main() diff -r 4a6b8f86b081 Modules/_tkinter.c --- a/Modules/_tkinter.c Mon Apr 15 23:14:55 2013 -0700 +++ b/Modules/_tkinter.c Tue Apr 16 10:06:44 2013 +0300 @@ -831,12 +831,18 @@ 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 (size > INT_MAX || size > UINT_MAX / 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 INT_MAX || size > UINT_MAX / 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); @@ -1010,7 +1020,7 @@ 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 */; @@ -1025,7 +1035,11 @@ objc = PyTuple_Size(args); if (objc > ARGSZ) { - objv = (Tcl_Obj **)ckalloc(objc * sizeof(char *)); + if (objc > INT_MAX || objc > UINT_MAX / 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;