[Python-checkins] cpython (merge 3.3 -> default): Issue #17119: Fixed integer overflows when processing large strings and tuples

serhiy.storchaka python-checkins at python.org
Wed Aug 21 20:56:37 CEST 2013


http://hg.python.org/cpython/rev/b500daaee7d0
changeset: 85297:b500daaee7d0
parent: 85291:49e23a3adf26
parent: 85296:6bc533d06cf1
user: Serhiy Storchaka <storchaka at gmail.com>
date: Wed Aug 21 21:43:08 2013 +0300
summary:
 Issue #17119: Fixed integer overflows when processing large strings and tuples
in the tkinter module.
files:
 Lib/test/test_tcl.py | 16 +++++++++++++++-
 Misc/NEWS | 3 +++
 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
--- 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 @@
 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()
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -38,6 +38,9 @@
 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
--- a/Modules/_tkinter.c
+++ b/Modules/_tkinter.c
@@ -47,6 +47,9 @@
 #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 @@
 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 @@
 
 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 @@
 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 @@
 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;
-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /