mirror of
https://github.com/python/cpython.git
synced 2025-11-02 03:01:58 +00:00
gh-130230: Fix crash in pow() with only Decimal third argument (GH-130237)
This commit is contained in:
parent
4374e1de87
commit
b93b7e566e
3 changed files with 29 additions and 1 deletions
|
|
@ -4481,6 +4481,15 @@ class Coverage:
|
||||||
self.assertIs(Decimal("NaN").fma(7, 1).is_nan(), True)
|
self.assertIs(Decimal("NaN").fma(7, 1).is_nan(), True)
|
||||||
# three arg power
|
# three arg power
|
||||||
self.assertEqual(pow(Decimal(10), 2, 7), 2)
|
self.assertEqual(pow(Decimal(10), 2, 7), 2)
|
||||||
|
if self.decimal == C:
|
||||||
|
self.assertEqual(pow(10, Decimal(2), 7), 2)
|
||||||
|
self.assertEqual(pow(10, 2, Decimal(7)), 2)
|
||||||
|
else:
|
||||||
|
# XXX: Three-arg power doesn't use __rpow__.
|
||||||
|
self.assertRaises(TypeError, pow, 10, Decimal(2), 7)
|
||||||
|
# XXX: There is no special method to dispatch on the
|
||||||
|
# third arg of three-arg power.
|
||||||
|
self.assertRaises(TypeError, pow, 10, 2, Decimal(7))
|
||||||
# exp
|
# exp
|
||||||
self.assertEqual(Decimal("1.01").exp(), 3)
|
self.assertEqual(Decimal("1.01").exp(), 3)
|
||||||
# is_normal
|
# is_normal
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Fix crash in :func:`pow` with only :class:`~decimal.Decimal` third argument.
|
||||||
|
|
@ -147,6 +147,24 @@ find_state_left_or_right(PyObject *left, PyObject *right)
|
||||||
return (decimal_state *)state;
|
return (decimal_state *)state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline decimal_state *
|
||||||
|
find_state_ternary(PyObject *left, PyObject *right, PyObject *modulus)
|
||||||
|
{
|
||||||
|
PyTypeObject *base;
|
||||||
|
if (PyType_GetBaseByToken(Py_TYPE(left), &dec_spec, &base) != 1) {
|
||||||
|
assert(!PyErr_Occurred());
|
||||||
|
if (PyType_GetBaseByToken(Py_TYPE(right), &dec_spec, &base) != 1) {
|
||||||
|
assert(!PyErr_Occurred());
|
||||||
|
PyType_GetBaseByToken(Py_TYPE(modulus), &dec_spec, &base);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(base != NULL);
|
||||||
|
void *state = _PyType_GetModuleState(base);
|
||||||
|
assert(state != NULL);
|
||||||
|
Py_DECREF(base);
|
||||||
|
return (decimal_state *)state;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#if !defined(MPD_VERSION_HEX) || MPD_VERSION_HEX < 0x02050000
|
#if !defined(MPD_VERSION_HEX) || MPD_VERSION_HEX < 0x02050000
|
||||||
#error "libmpdec version >= 2.5.0 required"
|
#error "libmpdec version >= 2.5.0 required"
|
||||||
|
|
@ -4407,7 +4425,7 @@ nm_mpd_qpow(PyObject *base, PyObject *exp, PyObject *mod)
|
||||||
PyObject *context;
|
PyObject *context;
|
||||||
uint32_t status = 0;
|
uint32_t status = 0;
|
||||||
|
|
||||||
decimal_state *state = find_state_left_or_right(base, exp);
|
decimal_state *state = find_state_ternary(base, exp, mod);
|
||||||
CURRENT_CONTEXT(state, context);
|
CURRENT_CONTEXT(state, context);
|
||||||
CONVERT_BINOP(&a, &b, base, exp, context);
|
CONVERT_BINOP(&a, &b, base, exp, context);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue