]> granicus.if.org Git - python/commitdiff
Fix for SF bug #576327: zipfile when sizeof(long) == 8
authorTim Peters <tim.peters@gmail.com>
Tue, 2 Jul 2002 20:20:08 +0000 (20:20 +0000)
committerTim Peters <tim.peters@gmail.com>
Tue, 2 Jul 2002 20:20:08 +0000 (20:20 +0000)
binascii_crc32():  Make this return a signed 4-byte result across
platforms.  The other way to make this platform-independent would be to
make it return an unsigned unbounded int, but the evidence suggests
other code out there treats it like a signed 4-byte int (e.g., existing
code writing the result with struct.pack "l" format).

Bugfix candidate.

Modules/binascii.c

index 6cba688fc7a9bbb50adc143e836b6c2689b2f60f..66644e196725f1468467cc51711d33e73e78418b 100644 (file)
@@ -864,6 +864,7 @@ binascii_crc32(PyObject *self, PyObject *args)
        unsigned char *bin_data;
        unsigned long crc = 0UL;        /* initial value of CRC */
        int len;
+       long result;
        
        if ( !PyArg_ParseTuple(args, "s#|l:crc32", &bin_data, &len, &crc) )
                return NULL;
@@ -872,7 +873,16 @@ binascii_crc32(PyObject *self, PyObject *args)
        while(len--)
                crc = crc_32_tab[(crc ^ *bin_data++) & 0xffUL] ^ (crc >> 8);
                /* Note:  (crc >> 8) MUST zero fill on left */
-       return Py_BuildValue("l", crc ^ 0xFFFFFFFFUL);
+
+       result = (long)(crc ^ 0xFFFFFFFFUL);
+       /* If long is > 32 bits, extend the sign bit.  This is one way to
+        * ensure the result is the same across platforms.  The other way
+        * would be to return an unbounded long, but the evidence suggests
+        * that lots of code outside this treats the result as if it were
+        * a signed 4-byte integer.
+        */
+       result |= -(result & (1L << 31));
+       return PyInt_FromLong(result);
 }