]> granicus.if.org Git - python/commitdiff
Merged revisions 68890 via svnmerge from
authorMark Dickinson <dickinsm@gmail.com>
Sat, 24 Jan 2009 15:56:57 +0000 (15:56 +0000)
committerMark Dickinson <dickinsm@gmail.com>
Sat, 24 Jan 2009 15:56:57 +0000 (15:56 +0000)
svn+ssh://pythondev@svn.python.org/python/trunk

........
  r68890 | mark.dickinson | 2009-01-24 15:27:44 +0000 (Sat, 24 Jan 2009) | 6 lines

  Issue #4393: fix 3 classes of potential portability problems in longobject.c:
   - fix some places where counters into ob_digit were declared as
     int instead of Py_ssize_t
   - add (twodigit) casts where necessary
   - fix code in _PyLong_AsByteArray that uses << on negative values
........

Objects/longobject.c

index a932df7edaaeada4df016a42b7249f83a3b0e549..7a3be9ecdda0cf3737d87e05151c6e8f7a0621f2 100644 (file)
@@ -742,7 +742,7 @@ _PyLong_FromByteArray(const unsigned char* bytes, size_t n,
                        /* Because we're going LSB to MSB, thisbyte is
                           more significant than what's already in accum,
                           so needs to be prepended to accum. */
-                       accum |= thisbyte << accumbits;
+                       accum |= (twodigits)thisbyte << accumbits;
                        accumbits += 8;
                        if (accumbits >= PyLong_SHIFT) {
                                /* There's enough to fill a Python digit. */
@@ -771,7 +771,7 @@ _PyLong_AsByteArray(PyLongObject* v,
                    unsigned char* bytes, size_t n,
                    int little_endian, int is_signed)
 {
-       int i;                  /* index into v->ob_digit */
+       Py_ssize_t i;           /* index into v->ob_digit */
        Py_ssize_t ndigits;             /* |v->ob_size| */
        twodigits accum;        /* sliding register */
        unsigned int accumbits; /* # bits in accum */
@@ -816,7 +816,7 @@ _PyLong_AsByteArray(PyLongObject* v,
        accumbits = 0;
        carry = do_twos_comp ? 1 : 0;
        for (i = 0; i < ndigits; ++i) {
-               twodigits thisdigit = v->ob_digit[i];
+               digit thisdigit = v->ob_digit[i];
                if (do_twos_comp) {
                        thisdigit = (thisdigit ^ PyLong_MASK) + carry;
                        carry = thisdigit >> PyLong_SHIFT;
@@ -825,26 +825,23 @@ _PyLong_AsByteArray(PyLongObject* v,
                /* Because we're going LSB to MSB, thisdigit is more
                   significant than what's already in accum, so needs to be
                   prepended to accum. */
-               accum |= thisdigit << accumbits;
-               accumbits += PyLong_SHIFT;
+               accum |= (twodigits)thisdigit << accumbits;
 
                /* The most-significant digit may be (probably is) at least
                   partly empty. */
                if (i == ndigits - 1) {
                        /* Count # of sign bits -- they needn't be stored,
                         * although for signed conversion we need later to
-                        * make sure at least one sign bit gets stored.
-                        * First shift conceptual sign bit to real sign bit.
-                        */
-                       stwodigits s = (stwodigits)(thisdigit <<
-                               (8*sizeof(stwodigits) - PyLong_SHIFT));
-                       unsigned int nsignbits = 0;
-                       while ((s < 0) == do_twos_comp && nsignbits < PyLong_SHIFT) {
-                               ++nsignbits;
-                               s <<= 1;
+                        * make sure at least one sign bit gets stored. */
+                       digit s = do_twos_comp ? thisdigit ^ PyLong_MASK :
+                                               thisdigit;
+                       while (s != 0) {
+                               s >>= 1;
+                               accumbits++;
                        }
-                       accumbits -= nsignbits;
                }
+               else
+                       accumbits += PyLong_SHIFT;
 
                /* Store as many bytes as possible. */
                while (accumbits >= 8) {
@@ -1364,7 +1361,7 @@ PyLong_AsUnsignedLongLongMask(register PyObject *op)
 static digit
 v_iadd(digit *x, Py_ssize_t m, digit *y, Py_ssize_t n)
 {
-       int i;
+       Py_ssize_t i;
        digit carry = 0;
 
        assert(m >= n);
@@ -1390,7 +1387,7 @@ v_iadd(digit *x, Py_ssize_t m, digit *y, Py_ssize_t n)
 static digit
 v_isub(digit *x, Py_ssize_t m, digit *y, Py_ssize_t n)
 {
-       int i;
+       Py_ssize_t i;
        digit borrow = 0;
 
        assert(m >= n);
@@ -1456,7 +1453,7 @@ inplace_divrem1(digit *pout, digit *pin, Py_ssize_t size, digit n)
                digit hi;
                rem = (rem << PyLong_SHIFT) + *--pin;
                *--pout = hi = (digit)(rem / n);
-               rem -= hi * n;
+               rem -= (twodigits)hi * n;
        }
        return (digit)rem;
 }
@@ -1715,11 +1712,11 @@ long_from_binary_base(char **str, int base)
        while (--p >= start) {
                int k = (int)_PyLong_DigitValue[Py_CHARMASK(*p)];
                assert(k >= 0 && k < base);
-               accum |= (twodigits)(k << bits_in_accum);
+               accum |= (twodigits)k << bits_in_accum;
                bits_in_accum += bits_per_char;
                if (bits_in_accum >= PyLong_SHIFT) {
                        *pdigit++ = (digit)(accum & PyLong_MASK);
-                       assert(pdigit - z->ob_digit <= (int)n);
+                       assert(pdigit - z->ob_digit <= n);
                        accum >>= PyLong_SHIFT;
                        bits_in_accum -= PyLong_SHIFT;
                        assert(bits_in_accum < PyLong_SHIFT);
@@ -1728,7 +1725,7 @@ long_from_binary_base(char **str, int base)
        if (bits_in_accum) {
                assert(bits_in_accum <= PyLong_SHIFT);
                *pdigit++ = (digit)accum;
-               assert(pdigit - z->ob_digit <= (int)n);
+               assert(pdigit - z->ob_digit <= n);
        }
        while (pdigit - z->ob_digit < n)
                *pdigit++ = 0;
@@ -2123,7 +2120,7 @@ x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem)
                digit vj = (j >= size_v) ? 0 : v->ob_digit[j];
                twodigits q;
                stwodigits carry = 0;
-               int i;
+               Py_ssize_t i;
 
                SIGCHECK({
                        Py_DECREF(a);
@@ -2325,7 +2322,7 @@ x_add(PyLongObject *a, PyLongObject *b)
 {
        Py_ssize_t size_a = ABS(Py_SIZE(a)), size_b = ABS(Py_SIZE(b));
        PyLongObject *z;
-       int i;
+       Py_ssize_t i;
        digit carry = 0;
 
        /* Ensure a is the larger of the two: */