summaryrefslogtreecommitdiffstats
path: root/Objects/longobject.c
diff options
context:
space:
mode:
authorGeorg Brandl <georg@python.org>2007-02-26 14:46:30 (GMT)
committerGeorg Brandl <georg@python.org>2007-02-26 14:46:30 (GMT)
commit61c31b07b9cb6aea725ee867ea3e9a3ddaa43985 (patch)
tree419223ea486c85de4a73ff90514d066d6c6e6ef9 /Objects/longobject.c
parentc145ef3728f3cf036ec4fee40734f2bfe33aeac1 (diff)
downloadcpython-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.c76
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