summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDennis Sweeney <36520290+sweeneyde@users.noreply.github.com>2023-02-27 10:46:40 (GMT)
committerGitHub <noreply@github.com>2023-02-27 10:46:40 (GMT)
commite3c3f9fec099fe78d2f98912be337d632f6fcdd1 (patch)
treed38597eae9ef4018b063e217f3c30147c09167fb
parent101a12c5767a8c6ca6e32b8e24a462d2606d24ca (diff)
downloadcpython-e3c3f9fec099fe78d2f98912be337d632f6fcdd1.zip
cpython-e3c3f9fec099fe78d2f98912be337d632f6fcdd1.tar.gz
cpython-e3c3f9fec099fe78d2f98912be337d632f6fcdd1.tar.bz2
gh-102250: Fix double-decref in COMPARE_AND_BRANCH error case (GH-102287)
-rw-r--r--Lib/test/test_bool.py20
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2023-02-26-23-10-32.gh-issue-102250.7MUKoC.rst1
-rw-r--r--Python/bytecodes.c4
-rw-r--r--Python/generated_cases.c.h4
4 files changed, 23 insertions, 6 deletions
diff --git a/Lib/test/test_bool.py b/Lib/test/test_bool.py
index b711ffb..916e22a 100644
--- a/Lib/test/test_bool.py
+++ b/Lib/test/test_bool.py
@@ -319,6 +319,26 @@ class BoolTest(unittest.TestCase):
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 0000000..17ab0cd
--- /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 ad68c79..7e9b36f 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 2987adc..271ba26 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);
}