summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorGregory P. Smith <greg@krypto.org>2022-03-20 21:46:52 (GMT)
committerGitHub <noreply@github.com>2022-03-20 21:46:52 (GMT)
commit4c989e19c84ec224655bbbde9422e16d4a838a80 (patch)
treedd6d234fbcba964c63d4bbbdaaec12b9e1dd2a09 /Modules
parent94f038cbb27dc6d1a74ae2bfedea674911f8e8c6 (diff)
downloadcpython-4c989e19c84ec224655bbbde9422e16d4a838a80.zip
cpython-4c989e19c84ec224655bbbde9422e16d4a838a80.tar.gz
cpython-4c989e19c84ec224655bbbde9422e16d4a838a80.tar.bz2
[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.
Diffstat (limited to 'Modules')
-rw-r--r--Modules/binascii.c22
1 files changed, 13 insertions, 9 deletions
diff --git a/Modules/binascii.c b/Modules/binascii.c
index 1f3248b..3777580 100644
--- a/Modules/binascii.c
+++ b/Modules/binascii.c
@@ -1120,16 +1120,20 @@ binascii_crc32_impl(PyObject *module, Py_buffer *data, unsigned int crc)
/*[clinic end generated code: output=52cf59056a78593b input=bbe340bc99d25aa8]*/
#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;
- Py_ssize_t len;
- int signed_val;
-
- buf = (Byte*)data->buf;
- len = data->len;
- signed_val = crc32(crc, buf, len);
- return (unsigned int)signed_val & 0xffffffffU;
+ unsigned char *buf = data->buf;
+ Py_ssize_t len = data->len;
+
+ /* Avoid truncation of length for very large buffers. crc32() takes
+ length as an unsigned int, which may be narrower than Py_ssize_t. */
+ while ((size_t)len > UINT_MAX) {
+ 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 */
{ /* By Jim Ahlstrom; All rights transferred to CNRI */