changeset: 92396:499b60b7d067 parent: 92391:135fc23e475c parent: 92395:1223c882253f user: Serhiy Storchaka date: Thu Sep 11 10:40:44 2014 +0300 files: Misc/NEWS Modules/_tkinter.c description: Issue #21951: Use attemptckalloc() instead of ckalloc() in Tkinter. ckalloc() causes the Tcl interpreter to panic, attemptckalloc() returns NULL if the memory allocation fails. diff -r 135fc23e475c -r 499b60b7d067 Misc/NEWS --- a/Misc/NEWS Wed Sep 10 23:32:36 2014 +0200 +++ b/Misc/NEWS Thu Sep 11 10:40:44 2014 +0300 @@ -132,6 +132,9 @@ 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 #12410: imaplib.IMAP4 now supports the context management protocol. diff -r 135fc23e475c -r 499b60b7d067 Modules/_tkinter.c --- a/Modules/_tkinter.c Wed Sep 10 23:32:36 2014 +0200 +++ b/Modules/_tkinter.c Thu Sep 11 10:40:44 2014 +0300 @@ -605,7 +605,7 @@ 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); @@ -639,7 +639,7 @@ if (use) len += strlen(use) + sizeof "-use "; - args = (char*)ckalloc(len); + args = (char*)attemptckalloc(len); if (!args) { PyErr_NoMemory(); Py_DECREF(v); @@ -912,7 +912,7 @@ "list 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) { PyErr_NoMemory(); return NULL; @@ -944,7 +944,7 @@ 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(); @@ -1111,7 +1111,7 @@ "list 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; @@ -1247,7 +1247,11 @@ 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; @@ -1498,8 +1502,11 @@ 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; @@ -2098,7 +2105,12 @@ #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; @@ -2144,7 +2156,11 @@ 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;