summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2014-09-11 07:38:54 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2014-09-11 07:38:54 (GMT)
commit07940883796e71135723616f06a1405105c09571 (patch)
tree3b4f2307324c6b254fdee133bd9c566cd88aa2ea
parent31a3ec313d442fd9d64a3882669da634d7b70d56 (diff)
downloadcpython-07940883796e71135723616f06a1405105c09571.zip
cpython-07940883796e71135723616f06a1405105c09571.tar.gz
cpython-07940883796e71135723616f06a1405105c09571.tar.bz2
Issue #21951: Use attemptckalloc() instead of ckalloc() in Tkinter.
ckalloc() causes the Tcl interpreter to panic, attemptckalloc() returns NULL if the memory allocation fails.
-rw-r--r--Misc/NEWS3
-rw-r--r--Modules/_tkinter.c36
2 files changed, 29 insertions, 10 deletions
diff --git a/Misc/NEWS b/Misc/NEWS
index 91125e7..6668877 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -32,6 +32,9 @@ Core and Builtins
Library
-------
+- Issue #21951: Tkinter now most likely raises MemoryError instead of crash
+ if the memory allocation fails.
+
- Issue #22338: Fix a crash in the json module on memory allocation failure.
- Issue #22226: First letter no longer is stripped from the "status" key in
diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c
index 83161fe..7871dec 100644
--- a/Modules/_tkinter.c
+++ b/Modules/_tkinter.c
@@ -598,7 +598,7 @@ Tkapp_New(char *screenName, char *className,
Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
/* This is used to get the application class for Tk 4.1 and up */
- argv0 = (char*)ckalloc(strlen(className) + 1);
+ argv0 = (char*)attemptckalloc(strlen(className) + 1);
if (!argv0) {
PyErr_NoMemory();
Py_DECREF(v);
@@ -632,7 +632,7 @@ Tkapp_New(char *screenName, char *className,
if (use)
len += strlen(use) + sizeof "-use ";
- args = (char*)ckalloc(len);
+ args = (char*)attemptckalloc(len);
if (!args) {
PyErr_NoMemory();
Py_DECREF(v);
@@ -903,7 +903,7 @@ AsObj(PyObject *value)
PyErr_SetString(PyExc_OverflowError, "tuple is too long");
return NULL;
}
- argv = (Tcl_Obj **) ckalloc(((size_t)size) * sizeof(Tcl_Obj *));
+ argv = (Tcl_Obj **) attemptckalloc(((size_t)size) * sizeof(Tcl_Obj *));
if(!argv)
return 0;
for (i = 0; i < size; i++)
@@ -933,7 +933,7 @@ AsObj(PyObject *value)
if (kind == sizeof(Tcl_UniChar))
return Tcl_NewUnicodeObj(inbuf, size);
allocsize = ((size_t)size) * sizeof(Tcl_UniChar);
- outbuf = (Tcl_UniChar*)ckalloc(allocsize);
+ outbuf = (Tcl_UniChar*)attemptckalloc(allocsize);
/* Else overflow occurred, and we take the next exit */
if (!outbuf) {
PyErr_NoMemory();
@@ -1098,7 +1098,7 @@ Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc)
PyErr_SetString(PyExc_OverflowError, "tuple is too long");
return NULL;
}
- objv = (Tcl_Obj **)ckalloc(((size_t)objc) * sizeof(Tcl_Obj *));
+ objv = (Tcl_Obj **)attemptckalloc(((size_t)objc) * sizeof(Tcl_Obj *));
if (objv == NULL) {
PyErr_NoMemory();
objc = 0;
@@ -1234,7 +1234,11 @@ Tkapp_Call(PyObject *selfptr, PyObject *args)
PyObject *exc_type, *exc_value, *exc_tb;
if (!WaitForMainloop(self))
return NULL;
- ev = (Tkapp_CallEvent*)ckalloc(sizeof(Tkapp_CallEvent));
+ ev = (Tkapp_CallEvent*)attemptckalloc(sizeof(Tkapp_CallEvent));
+ if (ev == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
ev->ev.proc = (Tcl_EventProc*)Tkapp_CallProc;
ev->self = self;
ev->args = args;
@@ -1485,8 +1489,11 @@ var_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags)
if (!WaitForMainloop(self))
return NULL;
- ev = (VarEvent*)ckalloc(sizeof(VarEvent));
-
+ ev = (VarEvent*)attemptckalloc(sizeof(VarEvent));
+ if (ev == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
ev->self = selfptr;
ev->args = args;
ev->flags = flags;
@@ -2082,7 +2089,12 @@ Tkapp_CreateCommand(PyObject *selfptr, PyObject *args)
#ifdef WITH_THREAD
if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
Tcl_Condition cond = NULL;
- CommandEvent *ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
+ CommandEvent *ev = (CommandEvent*)attemptckalloc(sizeof(CommandEvent));
+ if (ev == NULL) {
+ PyErr_NoMemory();
+ PyMem_DEL(data);
+ return NULL;
+ }
ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
ev->interp = self->interp;
ev->create = 1;
@@ -2128,7 +2140,11 @@ Tkapp_DeleteCommand(PyObject *selfptr, PyObject *args)
if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
Tcl_Condition cond = NULL;
CommandEvent *ev;
- ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
+ ev = (CommandEvent*)attemptckalloc(sizeof(CommandEvent));
+ if (ev == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
ev->interp = self->interp;
ev->create = 0;