summaryrefslogtreecommitdiffstats
path: root/Modules/_decimal/_decimal.c
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/_decimal/_decimal.c')
-rw-r--r--Modules/_decimal/_decimal.c38
1 files changed, 20 insertions, 18 deletions
diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c
index a85023a..60fc696 100644
--- a/Modules/_decimal/_decimal.c
+++ b/Modules/_decimal/_decimal.c
@@ -3203,7 +3203,8 @@ static PyObject *
dec_as_long(PyObject *dec, PyObject *context, int round)
{
PyLongObject *pylong;
- size_t maxsize, n;
+ digit *ob_digit;
+ size_t n;
Py_ssize_t i;
mpd_t *x;
mpd_context_t workctx;
@@ -3234,32 +3235,33 @@ dec_as_long(PyObject *dec, PyObject *context, int round)
return NULL;
}
- maxsize = mpd_sizeinbase(x, PyLong_BASE);
- if (maxsize > PY_SSIZE_T_MAX) {
- mpd_del(x);
- PyErr_NoMemory();
- return NULL;
- }
- pylong = _PyLong_New(maxsize);
- if (pylong == NULL) {
- mpd_del(x);
- return NULL;
- }
-
status = 0;
+ ob_digit = NULL;
#if PYLONG_BITS_IN_DIGIT == 30
- n = mpd_qexport_u32(pylong->ob_digit, maxsize, PyLong_BASE, x, &status);
+ n = mpd_qexport_u32(&ob_digit, 0, PyLong_BASE, x, &status);
#elif PYLONG_BITS_IN_DIGIT == 15
- n = mpd_qexport_u16(pylong->ob_digit, maxsize, PyLong_BASE, x, &status);
+ n = mpd_qexport_u16(&ob_digit, 0, PyLong_BASE, x, &status);
#else
- #error "PYLONG_BITS_IN_DIGIT should be 15 or 30"
+ #error "PYLONG_BITS_IN_DIGIT should be 15 or 30"
#endif
- if (dec_addstatus(context, status)) {
- Py_DECREF((PyObject *) pylong);
+
+ if (n == SIZE_MAX) {
+ PyErr_NoMemory();
+ mpd_del(x);
+ return NULL;
+ }
+
+ assert(n > 0);
+ pylong = _PyLong_New(n);
+ if (pylong == NULL) {
+ mpd_free(ob_digit);
mpd_del(x);
return NULL;
}
+ memcpy(pylong->ob_digit, ob_digit, n * sizeof(digit));
+ mpd_free(ob_digit);
+
i = n;
while ((i > 0) && (pylong->ob_digit[i-1] == 0)) {
i--;