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]

Reply via email to