https://github.com/python/cpython/commit/a03a696fd0c009e2e8e495078d4ab002dc9f202f commit: a03a696fd0c009e2e8e495078d4ab002dc9f202f branch: 3.15 author: sobolevn <[email protected]> committer: sobolevn <[email protected]> date: 2026-11-07T16:27:33Z summary:
[3.15] gh-161388: [tkinter] Fix crash on raising `__str__` method passed to `setvar` (GH-161397) (#161550) (cherry picked from commit 6026791c977a1df2ff8a427aad294388992ae078) Co-authored-by: sobolevn <[email protected]> files: M Lib/test/test_tcl.py M Modules/_tkinter.c diff --git a/Lib/test/test_tcl.py b/Lib/test/test_tcl.py index f6e49840d063bc..07f73b20c6c9bd 100644 --- a/Lib/test/test_tcl.py +++ b/Lib/test/test_tcl.py @@ -565,6 +565,29 @@ class List(list): self.assertEqual(self.passValue(values := [Value(), "pad"]), expect) self.assertEqual(self.passValue(values := List([Value(), "pad"])), expect) + 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 991ca2f9b9de28..69debec7b2941e 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -1198,8 +1198,9 @@ AsObj(PyObject *value) { PyObject *v = PyObject_Str(value); - if (!v) - return 0; + if (!v) { + return NULL; + } result = AsObj(v); Py_DECREF(v); return result; @@ -1936,6 +1937,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", _______________________________________________ Python-checkins mailing list -- [email protected] To unsubscribe send an email to [email protected] https://mail.python.org/mailman3//lists/python-checkins.python.org Member address: [email protected]
