Skip to content

Commit 4ac9b71

Browse files
miss-islington0z5asobolevn
authored
[3.14] gh-161387: Check the type of the decimal context ContextVar (GH-161399) (#161466)
gh-161387: Check the type of the decimal context `ContextVar` (GH-161399) (cherry picked from commit 4b50f88) Co-authored-by: 0z5a <dinadegttyarenko6@gmail.com> Co-authored-by: sobolevn <mail@sobolevn.me>
1 parent 9106913 commit 4ac9b71

3 files changed

Lines changed: 30 additions & 0 deletions

File tree

‎Lib/test/test_decimal.py‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3745,6 +3745,27 @@ def test_crashing_signal_dict_flags(self):
37453745
@requires_cdecimal
37463746
class CContextAPItests(ContextAPItests, unittest.TestCase):
37473747
decimal = C
3748+
3749+
def test_current_context_var_wrong_type(self):
3750+
# gh-161387
3751+
if not self.decimal.HAVE_CONTEXTVAR:
3752+
self.skipTest("_decimal built without context variables")
3753+
value = object()
3754+
context_vars = [var for var in contextvars.copy_context()
3755+
if var.name == "decimal_context"]
3756+
self.assertTrue(context_vars)
3757+
tokens = [var.set(value) for var in context_vars]
3758+
3759+
def restore():
3760+
for var, token in zip(context_vars, tokens):
3761+
var.reset(token)
3762+
3763+
self.addCleanup(restore)
3764+
with self.assertRaisesRegex(TypeError, "got object"):
3765+
self.decimal.Decimal(1) + self.decimal.Decimal(2)
3766+
for var in context_vars:
3767+
self.assertIs(var.get(), value)
3768+
37483769
class PyContextAPItests(ContextAPItests, unittest.TestCase):
37493770
decimal = P
37503771

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix a crash in :mod:`decimal` when the internal ``decimal_context``
2+
:class:`contextvars.ContextVar` holds a value that is not a context.

‎Modules/_decimal/_decimal.c‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1865,6 +1865,13 @@ current_context(decimal_state *state)
18651865
}
18661866

18671867
if (tl_context != NULL) {
1868+
if (!PyDecContext_Check(state, tl_context)) {
1869+
PyErr_Format(PyExc_TypeError,
1870+
"current decimal context must be a Context "
1871+
"instance, got %T", tl_context);
1872+
Py_DECREF(tl_context);
1873+
return NULL;
1874+
}
18681875
return tl_context;
18691876
}
18701877

0 commit comments

Comments
 (0)