]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
backport tim_one's checkin of
authorMichael W. Hudson <mwh@python.net>
Wed, 25 Sep 2002 10:22:50 +0000 (10:22 +0000)
committerMichael W. Hudson <mwh@python.net>
Wed, 25 Sep 2002 10:22:50 +0000 (10:22 +0000)
    revision 2.35 of binascii.c

Fix for SF bug #576327: zipfile when sizeof(long) == 8
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 70d60f02488629b074110b05c972166f38f935c8..9d710f5cb158d02460bcd509f2014cc0c159b575 100644 (file)
@@ -861,6 +861,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;
@@ -869,7 +870,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);
 }