diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2013-08-21 21:52:50 +0300 |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2013-08-21 21:52:50 +0300 |
commit | 707c58f6cf65059309693311372eed9c5705e1b5 (patch) | |
tree | 28db243c6d8a1cc7c97f8769d9f1aa48fd7bad3c | |
parent | 9b0808b4447e52b89e45e83c45fe14b11c916078 (diff) | |
parent | b7517ef372de8d3e7d2be2182962fe11f0a7ee60 (diff) | |
download | cpython-707c58f6cf65059309693311372eed9c5705e1b5.tar.gz |
Merge heads
-rw-r--r-- | Lib/test/test_tcl.py | 16 | ||||
-rw-r--r-- | Misc/NEWS | 3 | ||||
-rw-r--r-- | Modules/_tkinter.c | 29 |
3 files changed, 41 insertions, 7 deletions
diff --git a/Lib/test/test_tcl.py b/Lib/test/test_tcl.py index a5aaf9b725..91d324dcd3 100644 --- a/Lib/test/test_tcl.py +++ b/Lib/test/test_tcl.py @@ -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. @@ -236,8 +237,21 @@ class TclTest(unittest.TestCase): self.assertEqual(split(arg), res, msg=arg) +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() @@ -38,6 +38,9 @@ Core and Builtins Library ------- +- Issue #17119: Fixed integer overflows when processing large strings and tuples + in the tkinter module. + - Issue #18747: Re-seed OpenSSL's pseudo-random number generator after fork. A pthread_atfork() child handler is used to seeded the PRNG with pid, time and some stack data. 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; |