mirror of
https://github.com/python/cpython.git
synced 2025-07-23 19:25:40 +00:00
[3.10] bpo-38256: Fix binascii.crc32 large input. (GH-32000) (GH-32013)
Inputs >= 4GiB to `binascii.crc32(...)` when compiled to use the zlib crc32 implementation (the norm on POSIX) no longer return the wrong result.
This commit is contained in:
parent
94f038cbb2
commit
4c989e19c8
3 changed files with 26 additions and 9 deletions
|
@ -4,7 +4,7 @@ import unittest
|
||||||
import binascii
|
import binascii
|
||||||
import array
|
import array
|
||||||
import re
|
import re
|
||||||
from test.support import warnings_helper
|
from test.support import bigmemtest, _1G, _4G, warnings_helper
|
||||||
|
|
||||||
|
|
||||||
# Note: "*_hex" functions are aliases for "(un)hexlify"
|
# Note: "*_hex" functions are aliases for "(un)hexlify"
|
||||||
|
@ -449,6 +449,14 @@ class BytearrayBinASCIITest(BinASCIITest):
|
||||||
class MemoryviewBinASCIITest(BinASCIITest):
|
class MemoryviewBinASCIITest(BinASCIITest):
|
||||||
type2test = memoryview
|
type2test = memoryview
|
||||||
|
|
||||||
|
class ChecksumBigBufferTestCase(unittest.TestCase):
|
||||||
|
"""bpo-38256 - check that inputs >=4 GiB are handled correctly."""
|
||||||
|
|
||||||
|
@bigmemtest(size=_4G + 4, memuse=1, dry_run=False)
|
||||||
|
def test_big_buffer(self, size):
|
||||||
|
data = b"nyan" * (_1G + 1)
|
||||||
|
self.assertEqual(binascii.crc32(data), 1044521549)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
Fix :func:`binascii.crc32` when it is compiled to use zlib'c crc32 to
|
||||||
|
work properly on inputs 4+GiB in length instead of returning the wrong
|
||||||
|
result. The workaround prior to this was to always feed the function
|
||||||
|
data in increments smaller than 4GiB or to just call the zlib module
|
||||||
|
function.
|
|
@ -1120,16 +1120,20 @@ binascii_crc32_impl(PyObject *module, Py_buffer *data, unsigned int crc)
|
||||||
/*[clinic end generated code: output=52cf59056a78593b input=bbe340bc99d25aa8]*/
|
/*[clinic end generated code: output=52cf59056a78593b input=bbe340bc99d25aa8]*/
|
||||||
|
|
||||||
#ifdef USE_ZLIB_CRC32
|
#ifdef USE_ZLIB_CRC32
|
||||||
/* This was taken from zlibmodule.c PyZlib_crc32 (but is PY_SSIZE_T_CLEAN) */
|
/* The same core as zlibmodule.c zlib_crc32_impl. */
|
||||||
{
|
{
|
||||||
const Byte *buf;
|
unsigned char *buf = data->buf;
|
||||||
Py_ssize_t len;
|
Py_ssize_t len = data->len;
|
||||||
int signed_val;
|
|
||||||
|
|
||||||
buf = (Byte*)data->buf;
|
/* Avoid truncation of length for very large buffers. crc32() takes
|
||||||
len = data->len;
|
length as an unsigned int, which may be narrower than Py_ssize_t. */
|
||||||
signed_val = crc32(crc, buf, len);
|
while ((size_t)len > UINT_MAX) {
|
||||||
return (unsigned int)signed_val & 0xffffffffU;
|
crc = crc32(crc, buf, UINT_MAX);
|
||||||
|
buf += (size_t) UINT_MAX;
|
||||||
|
len -= (size_t) UINT_MAX;
|
||||||
|
}
|
||||||
|
crc = crc32(crc, buf, (unsigned int)len);
|
||||||
|
return crc & 0xffffffff;
|
||||||
}
|
}
|
||||||
#else /* USE_ZLIB_CRC32 */
|
#else /* USE_ZLIB_CRC32 */
|
||||||
{ /* By Jim Ahlstrom; All rights transferred to CNRI */
|
{ /* By Jim Ahlstrom; All rights transferred to CNRI */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue