diff --git a/Lib/test/test_tcl.py b/Lib/test/test_tcl.py index 1d90ac10ad77ade..004271fde2eac83 100644 --- a/Lib/test/test_tcl.py +++ b/Lib/test/test_tcl.py @@ -596,6 +596,29 @@ def test_returning_deeply_nested(self): % support.exceeds_recursion_limit()) self.assertRaises(RecursionError, interp.getvar, 'x') + def test_setvar_evil(self): + # gh-161388 + class StrRaises: + def __str__(self): + raise RuntimeError("setvar evil") + + value = StrRaises() + tk = self.interp.tk + + with self.assertRaisesRegex(RuntimeError, "setvar evil"): + tk.setvar("local_name1", value) + self.assertRaises(TclError, tk.getvar, "local_name1") + with self.assertRaisesRegex(RuntimeError, "setvar evil"): + tk.setvar("local_name2", "local_name3", value) + self.assertRaises(TclError, tk.getvar, "local_name2", "local_name3") + + with self.assertRaisesRegex(RuntimeError, "setvar evil"): + tk.globalsetvar("global_name1", value) + self.assertRaises(TclError, tk.globalgetvar, "global_name1") + with self.assertRaisesRegex(RuntimeError, "setvar evil"): + tk.globalsetvar("global_name2", "global_name3", value) + self.assertRaises(TclError, tk.globalgetvar, "global_name2", "global_name3") + def test_user_command(self): result = None def testfunc(arg): diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index 9a09687e55b9817..70a10cea038348d 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -1234,8 +1234,9 @@ AsObjNested(PyObject *value, int depth) { PyObject *v = PyObject_Str(value); - if (!v) - return 0; + if (!v) { + return NULL; + } result = AsObjNested(v, depth); Py_DECREF(v); return result; @@ -2101,6 +2102,9 @@ SetVar(TkappObject *self, PyObject *args, int flags) /* XXX must hold tcl lock already??? */ newval = AsObj(newValue); + if (newval == NULL) { + return NULL; + } if (self->trace) { if (flags & TCL_GLOBAL_ONLY) { TRACE(self, ("((sssNO))", "uplevel", "#0", "set",