]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-43660: Fix crash when displaying exceptions with custom values for sys.stderr...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Mon, 29 Mar 2021 23:24:33 +0000 (16:24 -0700)
committerGitHub <noreply@github.com>
Mon, 29 Mar 2021 23:24:33 +0000 (00:24 +0100)
(cherry picked from commit 09b90a037d18f5d4acdf1b14082e57bda78e85d3)

Co-authored-by: Pablo Galindo <Pablogsal@gmail.com>
Co-authored-by: Pablo Galindo <Pablogsal@gmail.com>
Lib/test/test_sys.py
Misc/NEWS.d/next/Core and Builtins/2021-03-29-19-50-34.bpo-43660.scTgag.rst [new file with mode: 0644]
Python/pythonrun.c

index fc6c1ef1acd7cdf6e3878f0eb473c4397689501d..fce6b98299f788ec592fd8d121dd8eeb0d573337 100644 (file)
@@ -1417,6 +1417,21 @@ class SizeofTest(unittest.TestCase):
         self.assertIsNone(cur.firstiter)
         self.assertIsNone(cur.finalizer)
 
+    def test_changing_sys_stderr_and_removing_reference(self):
+        # If the default displayhook doesn't take a strong reference
+        # to sys.stderr the following code can crash. See bpo-43660
+        # for more details.
+        code = textwrap.dedent('''
+            import sys
+            class MyStderr:
+                def write(self, s):
+                    sys.stderr = None
+            sys.stderr = MyStderr()
+            1/0
+        ''')
+        rc, out, err = assert_python_failure('-c', code)
+        self.assertEqual(out, b"")
+        self.assertEqual(err, b"")
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-03-29-19-50-34.bpo-43660.scTgag.rst b/Misc/NEWS.d/next/Core and Builtins/2021-03-29-19-50-34.bpo-43660.scTgag.rst
new file mode 100644 (file)
index 0000000..9841950
--- /dev/null
@@ -0,0 +1,3 @@
+Fix crash that happens when replacing ``sys.stderr`` with a callable that
+can remove the object while an exception is being printed. Patch by Pablo
+Galindo.
index 04540989f3043371a1493b624e6aa257f50dfd33..34cfb7f4b4fd7835be2a641c8a9e391764174870 100644 (file)
@@ -1072,8 +1072,9 @@ PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb)
     if (file == Py_None) {
         return;
     }
-
+    Py_INCREF(file);
     _PyErr_Display(file, exception, value, tb);
+    Py_DECREF(file);
 }
 
 PyObject *