diff options
author | Georg Brandl <georg@python.org> | 2007-02-26 14:46:30 (GMT) |
---|---|---|
committer | Georg Brandl <georg@python.org> | 2007-02-26 14:46:30 (GMT) |
commit | 61c31b07b9cb6aea725ee867ea3e9a3ddaa43985 (patch) | |
tree | 419223ea486c85de4a73ff90514d066d6c6e6ef9 /Objects/longobject.c | |
parent | c145ef3728f3cf036ec4fee40734f2bfe33aeac1 (diff) | |
download | cpython-61c31b07b9cb6aea725ee867ea3e9a3ddaa43985.zip cpython-61c31b07b9cb6aea725ee867ea3e9a3ddaa43985.tar.gz cpython-61c31b07b9cb6aea725ee867ea3e9a3ddaa43985.tar.bz2 |
Another refleak, this time in PyLong_AsLong. Fixes leaks showing in
test_getargs2 and test_email.
Diffstat (limited to 'Objects/longobject.c')
-rw-r--r-- | Objects/longobject.c | 76 |
1 files changed, 43 insertions, 33 deletions
diff --git a/Objects/longobject.c b/Objects/longobject.c index 22d4741..3b4a675 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -298,6 +298,7 @@ PyLong_AsLong(PyObject *vv) /* This version by Tim Peters */ register PyLongObject *v; unsigned long x, prev; + long res; Py_ssize_t i; int sign; int do_decref = 0; /* if nb_int was called */ @@ -326,46 +327,55 @@ PyLong_AsLong(PyObject *vv) } } + res = -1; v = (PyLongObject *)vv; i = v->ob_size; + switch (i) { - case -1: return -v->ob_digit[0]; - case 0: return 0; - case 1: return v->ob_digit[0]; - } - sign = 1; - x = 0; - if (i < 0) { - sign = -1; - i = -(i); - } - while (--i >= 0) { - prev = x; - x = (x << SHIFT) + v->ob_digit[i]; - if ((x >> SHIFT) != prev) - goto overflow; - } - if (do_decref) { - Py_DECREF(vv); - } - /* Haven't lost any bits, but casting to long requires extra care - * (see comment above). - */ - if (x <= (unsigned long)LONG_MAX) { - return (long)x * sign; - } - else if (sign < 0 && x == PY_ABS_LONG_MIN) { - return LONG_MIN; + case -1: + res = -v->ob_digit[0]; + break; + case 0: + res = 0; + break; + case 1: + res = v->ob_digit[0]; + break; + default: + sign = 1; + x = 0; + if (i < 0) { + sign = -1; + i = -(i); + } + while (--i >= 0) { + prev = x; + x = (x << SHIFT) + v->ob_digit[i]; + if ((x >> SHIFT) != prev) { + PyErr_SetString(PyExc_OverflowError, + "Python int too large to convert to C long"); + goto exit; + } + } + /* Haven't lost any bits, but casting to long requires extra care + * (see comment above). + */ + if (x <= (unsigned long)LONG_MAX) { + res = (long)x * sign; + } + else if (sign < 0 && x == PY_ABS_LONG_MIN) { + res = LONG_MIN; + } + else { + PyErr_SetString(PyExc_OverflowError, + "Python int too large to convert to C long"); + } } - /* else overflow */ - - overflow: + exit: if (do_decref) { Py_DECREF(vv); } - PyErr_SetString(PyExc_OverflowError, - "Python int too large to convert to C long"); - return -1; + return res; } int |