mirror of
https://github.com/python/cpython.git
synced 2025-11-18 18:31:56 +00:00
Another refleak, this time in PyLong_AsLong. Fixes leaks showing in
test_getargs2 and test_email.
This commit is contained in:
parent
c145ef3728
commit
61c31b07b9
1 changed files with 44 additions and 34 deletions
|
|
@ -298,6 +298,7 @@ PyLong_AsLong(PyObject *vv)
|
||||||
/* This version by Tim Peters */
|
/* This version by Tim Peters */
|
||||||
register PyLongObject *v;
|
register PyLongObject *v;
|
||||||
unsigned long x, prev;
|
unsigned long x, prev;
|
||||||
|
long res;
|
||||||
Py_ssize_t i;
|
Py_ssize_t i;
|
||||||
int sign;
|
int sign;
|
||||||
int do_decref = 0; /* if nb_int was called */
|
int do_decref = 0; /* if nb_int was called */
|
||||||
|
|
@ -326,13 +327,21 @@ PyLong_AsLong(PyObject *vv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
res = -1;
|
||||||
v = (PyLongObject *)vv;
|
v = (PyLongObject *)vv;
|
||||||
i = v->ob_size;
|
i = v->ob_size;
|
||||||
|
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case -1: return -v->ob_digit[0];
|
case -1:
|
||||||
case 0: return 0;
|
res = -v->ob_digit[0];
|
||||||
case 1: return v->ob_digit[0];
|
break;
|
||||||
}
|
case 0:
|
||||||
|
res = 0;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
res = v->ob_digit[0];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
sign = 1;
|
sign = 1;
|
||||||
x = 0;
|
x = 0;
|
||||||
if (i < 0) {
|
if (i < 0) {
|
||||||
|
|
@ -342,30 +351,31 @@ PyLong_AsLong(PyObject *vv)
|
||||||
while (--i >= 0) {
|
while (--i >= 0) {
|
||||||
prev = x;
|
prev = x;
|
||||||
x = (x << SHIFT) + v->ob_digit[i];
|
x = (x << SHIFT) + v->ob_digit[i];
|
||||||
if ((x >> SHIFT) != prev)
|
if ((x >> SHIFT) != prev) {
|
||||||
goto overflow;
|
PyErr_SetString(PyExc_OverflowError,
|
||||||
|
"Python int too large to convert to C long");
|
||||||
|
goto exit;
|
||||||
}
|
}
|
||||||
if (do_decref) {
|
|
||||||
Py_DECREF(vv);
|
|
||||||
}
|
}
|
||||||
/* Haven't lost any bits, but casting to long requires extra care
|
/* Haven't lost any bits, but casting to long requires extra care
|
||||||
* (see comment above).
|
* (see comment above).
|
||||||
*/
|
*/
|
||||||
if (x <= (unsigned long)LONG_MAX) {
|
if (x <= (unsigned long)LONG_MAX) {
|
||||||
return (long)x * sign;
|
res = (long)x * sign;
|
||||||
}
|
}
|
||||||
else if (sign < 0 && x == PY_ABS_LONG_MIN) {
|
else if (sign < 0 && x == PY_ABS_LONG_MIN) {
|
||||||
return LONG_MIN;
|
res = LONG_MIN;
|
||||||
}
|
}
|
||||||
/* else overflow */
|
else {
|
||||||
|
PyErr_SetString(PyExc_OverflowError,
|
||||||
overflow:
|
"Python int too large to convert to C long");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exit:
|
||||||
if (do_decref) {
|
if (do_decref) {
|
||||||
Py_DECREF(vv);
|
Py_DECREF(vv);
|
||||||
}
|
}
|
||||||
PyErr_SetString(PyExc_OverflowError,
|
return res;
|
||||||
"Python int too large to convert to C long");
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue