[Python-checkins] gh-102250: Fix double-decref in COMPARE_AND_BRANCH error case (GH-102287)

markshannon webhook-mailer at python.org
Mon Feb 27 05:47:16 EST 2023


https://github.com/python/cpython/commit/e3c3f9fec099fe78d2f98912be337d632f6fcdd1
commit: e3c3f9fec099fe78d2f98912be337d632f6fcdd1
branch: main
author: Dennis Sweeney <36520290+sweeneyde at users.noreply.github.com>
committer: markshannon <mark at hotpy.org>
date: 2023-02-27T10:46:40Z
summary:

gh-102250: Fix double-decref in COMPARE_AND_BRANCH error case (GH-102287)

files:
A Misc/NEWS.d/next/Core and Builtins/2023-02-26-23-10-32.gh-issue-102250.7MUKoC.rst
M Lib/test/test_bool.py
M Python/bytecodes.c
M Python/generated_cases.c.h

diff --git a/Lib/test/test_bool.py b/Lib/test/test_bool.py
index b711ffb9a3ec..916e22a527a8 100644
--- a/Lib/test/test_bool.py
+++ b/Lib/test/test_bool.py
@@ -319,6 +319,26 @@ def __len__(self):
                 return -1
         self.assertRaises(ValueError, bool, Eggs())
 
+    def test_interpreter_convert_to_bool_raises(self):
+        class SymbolicBool:
+            def __bool__(self):
+                raise TypeError
+
+        class Symbol:
+            def __gt__(self, other):
+                return SymbolicBool()
+
+        x = Symbol()
+
+        with self.assertRaises(TypeError):
+            if x > 0:
+                msg = "x > 0 was true"
+            else:
+                msg = "x > 0 was false"
+
+        # This used to create negative refcounts, see gh-102250
+        del x
+
     def test_from_bytes(self):
         self.assertIs(bool.from_bytes(b'\x00'*8, 'big'), False)
         self.assertIs(bool.from_bytes(b'abcd', 'little'), True)
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-02-26-23-10-32.gh-issue-102250.7MUKoC.rst b/Misc/NEWS.d/next/Core and Builtins/2023-02-26-23-10-32.gh-issue-102250.7MUKoC.rst
new file mode 100644
index 000000000000..17ab0cd43679
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2023-02-26-23-10-32.gh-issue-102250.7MUKoC.rst	
@@ -0,0 +1 @@
+Fixed a segfault occurring when the interpreter calls a ``__bool__`` method that raises.
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index ad68c794fe7a..7e9b36f69721 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -1754,9 +1754,7 @@ dummy_func(
             int offset = next_instr[1].op.arg;
             int err = PyObject_IsTrue(cond);
             Py_DECREF(cond);
-            if (err < 0) {
-                goto error;
-            }
+            ERROR_IF(err < 0, error);
             if (jump_on_true == (err != 0)) {
                 JUMPBY(offset);
             }
diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h
index 2987adc3bba5..271ba26f4895 100644
--- a/Python/generated_cases.c.h
+++ b/Python/generated_cases.c.h
@@ -2205,9 +2205,7 @@
             int offset = next_instr[1].op.arg;
             int err = PyObject_IsTrue(cond);
             Py_DECREF(cond);
-            if (err < 0) {
-                goto error;
-            }
+            if (err < 0) goto pop_2_error;
             if (jump_on_true == (err != 0)) {
                 JUMPBY(offset);
             }



More information about the Python-checkins mailing list