diff -r 5b0fda8f5718 Objects/longobject.c --- a/Objects/longobject.c Fri May 02 22:31:14 2014 +0200 +++ b/Objects/longobject.c Fri May 02 23:06:22 2014 +0200 @@ -180,27 +180,37 @@ PyLongObject * #define MAX_LONG_DIGITS \ ((PY_SSIZE_T_MAX - offsetof(PyLongObject, ob_digit))/sizeof(digit)) +static PyLongObject * +long_alloc(Py_ssize_t ndigits, int use_calloc) +{ + PyLongObject *result; + Py_ssize_t size; + /* Number of bytes needed is: offsetof(PyLongObject, ob_digit) + + sizeof(digit)*ndigits. Previous incarnations of this code used + sizeof(PyVarObject) instead of the offsetof, but this risks being + incorrect in the presence of padding between the PyVarObject header + and the digits. */ + if (ndigits > (Py_ssize_t)MAX_LONG_DIGITS) { + PyErr_SetString(PyExc_OverflowError, + "too many digits in integer"); + return NULL; + } + size = offsetof(PyLongObject, ob_digit) + ndigits * sizeof(digit); + if (use_calloc) + result = PyObject_Calloc(1, size); + else + result = PyObject_Malloc(size); + if (!result) { + PyErr_NoMemory(); + return NULL; + } + return (PyLongObject*)PyObject_INIT_VAR(result, &PyLong_Type, ndigits); +} + PyLongObject * _PyLong_New(Py_ssize_t size) { - PyLongObject *result; - /* Number of bytes needed is: offsetof(PyLongObject, ob_digit) + - sizeof(digit)*size. Previous incarnations of this code used - sizeof(PyVarObject) instead of the offsetof, but this risks being - incorrect in the presence of padding between the PyVarObject header - and the digits. */ - if (size > (Py_ssize_t)MAX_LONG_DIGITS) { - PyErr_SetString(PyExc_OverflowError, - "too many digits in integer"); - return NULL; - } - result = PyObject_MALLOC(offsetof(PyLongObject, ob_digit) + - size*sizeof(digit)); - if (!result) { - PyErr_NoMemory(); - return NULL; - } - return (PyLongObject*)PyObject_INIT_VAR(result, &PyLong_Type, size); + return long_alloc(size, 0); } PyObject * @@ -4126,15 +4136,13 @@ long_lshift(PyObject *v, PyObject *w) newsize = oldsize + wordshift; if (remshift) ++newsize; - z = _PyLong_New(newsize); + z = long_alloc(newsize, 1); if (z == NULL) return NULL; if (Py_SIZE(a) < 0) { assert(Py_REFCNT(z) == 1); Py_SIZE(z) = -Py_SIZE(z); } - for (i = 0; i < wordshift; i++) - z->ob_digit[i] = 0; accum = 0; for (i = wordshift, j = 0; j < oldsize; i++, j++) { accum |= (twodigits)a->ob_digit[j] << remshift;