From: Serhiy Storchaka Date: Mon, 11 Apr 2016 06:57:37 +0000 (+0300) Subject: Issue #26200: Restored more safe usages of Py_SETREF. X-Git-Tag: v3.6.0a1~236 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=59865e7fe158bcedc0c2b6252593650b018cf738;p=thirdparty%2FPython%2Fcpython.git Issue #26200: Restored more safe usages of Py_SETREF. --- 59865e7fe158bcedc0c2b6252593650b018cf738 diff --cc Modules/_decimal/_decimal.c index 0c02d28db77d,112b44fda7b5..3c2ad851baf3 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@@ -3380,106 -3380,6 +3380,106 @@@ dec_as_long(PyObject *dec, PyObject *co return (PyObject *) pylong; } +/* Convert a Decimal to its exact integer ratio representation. */ +static PyObject * +dec_as_integer_ratio(PyObject *self, PyObject *args UNUSED) +{ + PyObject *numerator = NULL; + PyObject *denominator = NULL; + PyObject *exponent = NULL; + PyObject *result = NULL; + PyObject *tmp; + mpd_ssize_t exp; + PyObject *context; + uint32_t status = 0; + PyNumberMethods *long_methods = PyLong_Type.tp_as_number; + + if (mpd_isspecial(MPD(self))) { + if (mpd_isnan(MPD(self))) { + PyErr_SetString(PyExc_ValueError, + "cannot convert NaN to integer ratio"); + } + else { + PyErr_SetString(PyExc_OverflowError, + "cannot convert Infinity to integer ratio"); + } + return NULL; + } + + CURRENT_CONTEXT(context); + + tmp = dec_alloc(); + if (tmp == NULL) { + return NULL; + } + + if (!mpd_qcopy(MPD(tmp), MPD(self), &status)) { + Py_DECREF(tmp); + PyErr_NoMemory(); + return NULL; + } + + exp = mpd_iszero(MPD(tmp)) ? 0 : MPD(tmp)->exp; + MPD(tmp)->exp = 0; + + /* context and rounding are unused here: the conversion is exact */ + numerator = dec_as_long(tmp, context, MPD_ROUND_FLOOR); + Py_DECREF(tmp); + if (numerator == NULL) { + goto error; + } + + exponent = PyLong_FromSsize_t(exp < 0 ? -exp : exp); + if (exponent == NULL) { + goto error; + } + + tmp = PyLong_FromLong(10); + if (tmp == NULL) { + goto error; + } + - Py_XSETREF(exponent, long_methods->nb_power(tmp, exponent, Py_None)); ++ Py_SETREF(exponent, long_methods->nb_power(tmp, exponent, Py_None)); + Py_DECREF(tmp); + if (exponent == NULL) { + goto error; + } + + if (exp >= 0) { - Py_XSETREF(numerator, long_methods->nb_multiply(numerator, exponent)); ++ Py_SETREF(numerator, long_methods->nb_multiply(numerator, exponent)); + if (numerator == NULL) { + goto error; + } + denominator = PyLong_FromLong(1); + if (denominator == NULL) { + goto error; + } + } + else { + denominator = exponent; + exponent = NULL; + tmp = _PyLong_GCD(numerator, denominator); + if (tmp == NULL) { + goto error; + } - Py_XSETREF(numerator, long_methods->nb_floor_divide(numerator, tmp)); - Py_XSETREF(denominator, long_methods->nb_floor_divide(denominator, tmp)); ++ Py_SETREF(numerator, long_methods->nb_floor_divide(numerator, tmp)); ++ Py_SETREF(denominator, long_methods->nb_floor_divide(denominator, tmp)); + Py_DECREF(tmp); + if (numerator == NULL || denominator == NULL) { + goto error; + } + } + + result = PyTuple_Pack(2, numerator, denominator); + + +error: + Py_XDECREF(exponent); + Py_XDECREF(denominator); + Py_XDECREF(numerator); + return result; +} + static PyObject * PyDec_ToIntegralValue(PyObject *dec, PyObject *args, PyObject *kwds) { diff --cc Objects/floatobject.c index 32a0de1f3bbf,d92bec35b5f8..eb60659615fb --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@@ -1483,27 -1489,24 +1483,27 @@@ float_as_integer_ratio(PyObject *v, PyO to be truncated by PyLong_FromDouble(). */ numerator = PyLong_FromDouble(float_part); - if (numerator == NULL) goto error; + if (numerator == NULL) + goto error; + denominator = PyLong_FromLong(1); + if (denominator == NULL) + goto error; + py_exponent = PyLong_FromLong(Py_ABS(exponent)); + if (py_exponent == NULL) + goto error; /* fold in 2**exponent */ - denominator = PyLong_FromLong(1); - py_exponent = PyLong_FromLong(labs((long)exponent)); - if (py_exponent == NULL) goto error; - INPLACE_UPDATE(py_exponent, - long_methods->nb_lshift(denominator, py_exponent)); - if (py_exponent == NULL) goto error; if (exponent > 0) { - Py_XSETREF(numerator, - INPLACE_UPDATE(numerator, - long_methods->nb_multiply(numerator, py_exponent)); - if (numerator == NULL) goto error; ++ Py_SETREF(numerator, + long_methods->nb_lshift(numerator, py_exponent)); + if (numerator == NULL) + goto error; } else { - Py_XSETREF(denominator, - Py_DECREF(denominator); - denominator = py_exponent; - py_exponent = NULL; ++ Py_SETREF(denominator, + long_methods->nb_lshift(denominator, py_exponent)); + if (denominator == NULL) + goto error; } result_pair = PyTuple_Pack(2, numerator, denominator);