mirror of https://github.com/python/cpython
Issue #17119: Fixed integer overflows when processing large strings and tuples
in the tkinter module.
This commit is contained in:
commit
4e4088d273
|
@ -3,6 +3,7 @@
|
||||||
import unittest
|
import unittest
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
import _testcapi
|
||||||
from test import support
|
from test import support
|
||||||
|
|
||||||
# Skip this test if the _tkinter module wasn't built.
|
# 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)
|
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():
|
def test_main():
|
||||||
support.run_unittest(TclTest, TkinterTest)
|
support.run_unittest(TclTest, TkinterTest, BigmemTclTest)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
test_main()
|
test_main()
|
||||||
|
|
|
@ -38,6 +38,9 @@ Core and Builtins
|
||||||
Library
|
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.
|
- 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
|
A pthread_atfork() child handler is used to seeded the PRNG with pid, time
|
||||||
and some stack data.
|
and some stack data.
|
||||||
|
|
|
@ -47,6 +47,9 @@ Copyright (C) 1994 Steen Lumholt.
|
||||||
#define PyBool_FromLong PyLong_FromLong
|
#define PyBool_FromLong PyLong_FromLong
|
||||||
#endif
|
#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,
|
/* Starting with Tcl 8.4, many APIs offer const-correctness. Unfortunately,
|
||||||
making _tkinter correct for this API means to break earlier
|
making _tkinter correct for this API means to break earlier
|
||||||
versions. USE_COMPAT_CONST allows to make _tkinter work with both 8.4 and
|
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))
|
else if (PyFloat_Check(value))
|
||||||
return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
|
return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
|
||||||
else if (PyTuple_Check(value)) {
|
else if (PyTuple_Check(value)) {
|
||||||
Tcl_Obj **argv = (Tcl_Obj**)
|
Tcl_Obj **argv;
|
||||||
ckalloc(PyTuple_Size(value)*sizeof(Tcl_Obj*));
|
Py_ssize_t size, i;
|
||||||
int 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)
|
if(!argv)
|
||||||
return 0;
|
return 0;
|
||||||
for(i=0;i<PyTuple_Size(value);i++)
|
for (i = 0; i < size; i++)
|
||||||
argv[i] = AsObj(PyTuple_GetItem(value,i));
|
argv[i] = AsObj(PyTuple_GetItem(value,i));
|
||||||
result = Tcl_NewListObj(PyTuple_Size(value), argv);
|
result = Tcl_NewListObj(PyTuple_Size(value), argv);
|
||||||
ckfree(FREECAST argv);
|
ckfree(FREECAST argv);
|
||||||
|
@ -874,6 +883,10 @@ AsObj(PyObject *value)
|
||||||
|
|
||||||
inbuf = PyUnicode_DATA(value);
|
inbuf = PyUnicode_DATA(value);
|
||||||
size = PyUnicode_GET_LENGTH(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);
|
kind = PyUnicode_KIND(value);
|
||||||
allocsize = ((size_t)size) * sizeof(Tcl_UniChar);
|
allocsize = ((size_t)size) * sizeof(Tcl_UniChar);
|
||||||
outbuf = (Tcl_UniChar*)ckalloc(allocsize);
|
outbuf = (Tcl_UniChar*)ckalloc(allocsize);
|
||||||
|
@ -1029,7 +1042,7 @@ static Tcl_Obj**
|
||||||
Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc)
|
Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc)
|
||||||
{
|
{
|
||||||
Tcl_Obj **objv = objStore;
|
Tcl_Obj **objv = objStore;
|
||||||
int objc = 0, i;
|
Py_ssize_t objc = 0, i;
|
||||||
if (args == NULL)
|
if (args == NULL)
|
||||||
/* do nothing */;
|
/* do nothing */;
|
||||||
|
|
||||||
|
@ -1044,7 +1057,11 @@ Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc)
|
||||||
objc = PyTuple_Size(args);
|
objc = PyTuple_Size(args);
|
||||||
|
|
||||||
if (objc > ARGSZ) {
|
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) {
|
if (objv == NULL) {
|
||||||
PyErr_NoMemory();
|
PyErr_NoMemory();
|
||||||
objc = 0;
|
objc = 0;
|
||||||
|
|
Loading…
Reference in New Issue