Skip to content

Commit f3eb3cc

Browse files
authored
[3.14] gh-161388: [tkinter] Fix crash on raising __str__ method passed to setvar (GH-161397) (#161551)
(cherry picked from commit 6026791)
1 parent 797faea commit f3eb3cc

2 files changed

Lines changed: 29 additions & 2 deletions

File tree

‎Lib/test/test_tcl.py‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,29 @@ class List(list):
565565
self.assertEqual(self.passValue(values := [Value(), "pad"]), expect)
566566
self.assertEqual(self.passValue(values := List([Value(), "pad"])), expect)
567567

568+
def test_setvar_evil(self):
569+
# gh-161388
570+
class StrRaises:
571+
def __str__(self):
572+
raise RuntimeError("setvar evil")
573+
574+
value = StrRaises()
575+
tk = self.interp.tk
576+
577+
with self.assertRaisesRegex(RuntimeError, "setvar evil"):
578+
tk.setvar("local_name1", value)
579+
self.assertRaises(TclError, tk.getvar, "local_name1")
580+
with self.assertRaisesRegex(RuntimeError, "setvar evil"):
581+
tk.setvar("local_name2", "local_name3", value)
582+
self.assertRaises(TclError, tk.getvar, "local_name2", "local_name3")
583+
584+
with self.assertRaisesRegex(RuntimeError, "setvar evil"):
585+
tk.globalsetvar("global_name1", value)
586+
self.assertRaises(TclError, tk.globalgetvar, "global_name1")
587+
with self.assertRaisesRegex(RuntimeError, "setvar evil"):
588+
tk.globalsetvar("global_name2", "global_name3", value)
589+
self.assertRaises(TclError, tk.globalgetvar, "global_name2", "global_name3")
590+
568591
def test_user_command(self):
569592
result = None
570593
def testfunc(arg):

‎Modules/_tkinter.c‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,8 +1220,9 @@ AsObj(PyObject *value)
12201220

12211221
{
12221222
PyObject *v = PyObject_Str(value);
1223-
if (!v)
1224-
return 0;
1223+
if (!v) {
1224+
return NULL;
1225+
}
12251226
result = AsObj(v);
12261227
Py_DECREF(v);
12271228
return result;
@@ -1958,6 +1959,9 @@ SetVar(TkappObject *self, PyObject *args, int flags)
19581959

19591960
/* XXX must hold tcl lock already??? */
19601961
newval = AsObj(newValue);
1962+
if (newval == NULL) {
1963+
return NULL;
1964+
}
19611965
if (self->trace) {
19621966
if (flags & TCL_GLOBAL_ONLY) {
19631967
TRACE(self, ("((sssNO))", "uplevel", "#0", "set",

0 commit comments

Comments
 (0)