mirror of
https://github.com/python/cpython.git
synced 2025-11-01 10:45:30 +00:00
Force zlib.crc32 and zlib.adler32 to return a signed integer on all platforms
regardless of the native sizeof(long) used in the integer object. This somewhat odd behavior of returning a signed is maintained in 2.x for compatibility reasons of always returning an integer rather than a long object. Fixes Issue1202 for Python 2.6
This commit is contained in:
parent
33451d8ab1
commit
f48f9d38c0
4 changed files with 42 additions and 8 deletions
|
|
@ -42,6 +42,12 @@ The available exception and functions in this module are:
|
|||
the algorithm is designed for use as a checksum algorithm, it is not suitable
|
||||
for use as a general hash algorithm.
|
||||
|
||||
This function always returns an integer object.
|
||||
|
||||
.. versionchanged:: 2.6
|
||||
For consistent cross-platform behavior we always return a signed integer.
|
||||
ie: Results in the (2**31)...(2**32-1) range will be negative.
|
||||
|
||||
|
||||
.. function:: compress(string[, level])
|
||||
|
||||
|
|
@ -74,6 +80,12 @@ The available exception and functions in this module are:
|
|||
the algorithm is designed for use as a checksum algorithm, it is not suitable
|
||||
for use as a general hash algorithm.
|
||||
|
||||
This function always returns an integer object.
|
||||
|
||||
.. versionchanged:: 2.6
|
||||
For consistent cross-platform behavior we always return a signed integer.
|
||||
ie: Results in the (2**31)...(2**32-1) range will be negative.
|
||||
|
||||
|
||||
.. function:: decompress(string[, wbits[, bufsize]])
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,15 @@ class ChecksumTestCase(unittest.TestCase):
|
|||
self.assertEqual(zlib.crc32("penguin"), zlib.crc32("penguin", 0))
|
||||
self.assertEqual(zlib.adler32("penguin"),zlib.adler32("penguin",1))
|
||||
|
||||
def test_abcdefghijklmnop(self):
|
||||
"""test issue1202 compliance: signed crc32, adler32 in 2.x"""
|
||||
foo = 'abcdefghijklmnop'
|
||||
# explicitly test signed behavior
|
||||
self.assertEqual(zlib.crc32(foo), -1808088941)
|
||||
self.assertEqual(zlib.crc32('spam'), 1138425661)
|
||||
self.assertEqual(zlib.adler32(foo+foo), -721416943)
|
||||
self.assertEqual(zlib.adler32('spam'), 72286642)
|
||||
|
||||
|
||||
|
||||
class ExceptionTestCase(unittest.TestCase):
|
||||
|
|
|
|||
|
|
@ -27,6 +27,10 @@ Core and builtins
|
|||
Library
|
||||
-------
|
||||
|
||||
- Issue #1202: zlib.crc32 and zlib.adler32 no longer return different values
|
||||
on 32-bit vs. 64-bit python interpreters. Both were correct, but they now
|
||||
both return a signed integer object for consistency.
|
||||
|
||||
- Issue #1158: add %f format (fractions of a second represented as
|
||||
microseconds) to datetime objects. Understood by both strptime and
|
||||
strftime.
|
||||
|
|
|
|||
|
|
@ -884,37 +884,46 @@ PyDoc_STRVAR(adler32__doc__,
|
|||
"adler32(string[, start]) -- Compute an Adler-32 checksum of string.\n"
|
||||
"\n"
|
||||
"An optional starting value can be specified. The returned checksum is\n"
|
||||
"an integer.");
|
||||
"a signed integer.");
|
||||
|
||||
static PyObject *
|
||||
PyZlib_adler32(PyObject *self, PyObject *args)
|
||||
{
|
||||
uLong adler32val = adler32(0L, Z_NULL, 0);
|
||||
Byte *buf;
|
||||
int len;
|
||||
int len, signed_val;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s#|k:adler32", &buf, &len, &adler32val))
|
||||
return NULL;
|
||||
adler32val = adler32(adler32val, buf, len);
|
||||
return PyInt_FromLong(adler32val);
|
||||
/* In Python 2.x we return a signed integer regardless of native platform
|
||||
* long size (the 32bit unsigned long is treated as 32-bit signed and sign
|
||||
* extended into a 64-bit long inside the integer object). 3.0 does the
|
||||
* right thing and returns unsigned. http://bugs.python.org/issue1202 */
|
||||
signed_val = adler32(adler32val, buf, len);
|
||||
return PyInt_FromLong(signed_val);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(crc32__doc__,
|
||||
"crc32(string[, start]) -- Compute a CRC-32 checksum of string.\n"
|
||||
"\n"
|
||||
"An optional starting value can be specified. The returned checksum is\n"
|
||||
"an integer.");
|
||||
"a signed integer.");
|
||||
|
||||
static PyObject *
|
||||
PyZlib_crc32(PyObject *self, PyObject *args)
|
||||
{
|
||||
uLong crc32val = crc32(0L, Z_NULL, 0);
|
||||
Byte *buf;
|
||||
int len;
|
||||
int len, signed_val;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s#|k:crc32", &buf, &len, &crc32val))
|
||||
return NULL;
|
||||
crc32val = crc32(crc32val, buf, len);
|
||||
return PyInt_FromLong(crc32val);
|
||||
/* In Python 2.x we return a signed integer regardless of native platform
|
||||
* long size (the 32bit unsigned long is treated as 32-bit signed and sign
|
||||
* extended into a 64-bit long inside the integer object). 3.0 does the
|
||||
* right thing and returns unsigned. http://bugs.python.org/issue1202 */
|
||||
signed_val = crc32(crc32val, buf, len);
|
||||
return PyInt_FromLong(signed_val);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue