diff -r 13307eb5bf47 Objects/longobject.c --- a/Objects/longobject.c Sat Apr 14 14:20:29 2012 -0500 +++ b/Objects/longobject.c Sun Apr 15 23:29:34 2012 +0300 @@ -1672,11 +1672,10 @@ { register PyLongObject *a = (PyLongObject *)aa; PyObject *v; - Py_ssize_t i, sz; + Py_ssize_t sz; Py_ssize_t size_a; - char *p; - char sign = '\0'; - char *buffer; + Py_UCS1 *p; + int negative; int bits; assert(base == 2 || base == 8 || base == 10 || base == 16); @@ -1688,6 +1687,7 @@ return NULL; } size_a = ABS(Py_SIZE(a)); + negative = Py_SIZE(a) < 0; /* Compute a rough upper bound for the length of the string */ switch (base) { @@ -1706,31 +1706,37 @@ } /* compute length of output string: allow 2 characters for prefix and 1 for possible '-' sign. */ - if (size_a > (PY_SSIZE_T_MAX - 3) / PyLong_SHIFT / sizeof(Py_UCS4)) { + if (size_a > (PY_SSIZE_T_MAX - 3) / PyLong_SHIFT) { PyErr_SetString(PyExc_OverflowError, "int is too large to format"); return NULL; } /* now size_a * PyLong_SHIFT + 3 <= PY_SSIZE_T_MAX, so the RHS below is safe from overflow */ - sz = 3 + (size_a * PyLong_SHIFT + (bits - 1)) / bits; - assert(sz >= 0); - buffer = PyMem_Malloc(sz); - if (buffer == NULL) { + if (size_a == 0) { + sz = 3; + } + else { + sz = 2 + negative + ((size_a - 1) * PyLong_SHIFT + + bits_in_digit(a->ob_digit[size_a - 1]) + + (bits - 1)) / bits; + } + v = PyUnicode_New(sz, 'f'); + if (v == NULL) { PyErr_NoMemory(); return NULL; } - p = &buffer[sz]; - if (Py_SIZE(a) < 0) - sign = '-'; - - if (Py_SIZE(a) == 0) { + assert(PyUnicode_KIND(v) == PyUnicode_1BYTE_KIND); + p = PyUnicode_1BYTE_DATA(v) + sz; + + if (size_a == 0) { *--p = '0'; } else { /* JRH: special case for power-of-2 bases */ twodigits accum = 0; int accumbits = 0; /* # of bits in accum */ + Py_ssize_t i; for (i = 0; i < size_a; ++i) { accum |= (twodigits)a->ob_digit[i] << accumbits; accumbits += PyLong_SHIFT; @@ -1739,7 +1745,7 @@ char cdigit; cdigit = (char)(accum & (base - 1)); cdigit += (cdigit < 10) ? '0' : 'a'-10; - assert(p > buffer); + assert(p > PyUnicode_1BYTE_DATA(v)); *--p = cdigit; accumbits -= bits; accum >>= bits; @@ -1747,6 +1753,7 @@ } } + assert(p == PyUnicode_1BYTE_DATA(v) + 2 + negative); if (base == 16) *--p = 'x'; else if (base == 8) @@ -1754,10 +1761,8 @@ else /* (base == 2) */ *--p = 'b'; *--p = '0'; - if (sign) - *--p = sign; - v = PyUnicode_DecodeASCII(p, &buffer[sz] - p, NULL); - PyMem_Free(buffer); + if (negative) + *--p = '-'; return v; }