diff options
author | Gregory P. Smith <greg@krypto.org> | 2022-03-20 21:46:52 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-20 21:46:52 (GMT) |
commit | 4c989e19c84ec224655bbbde9422e16d4a838a80 (patch) | |
tree | dd6d234fbcba964c63d4bbbdaaec12b9e1dd2a09 /Modules | |
parent | 94f038cbb27dc6d1a74ae2bfedea674911f8e8c6 (diff) | |
download | cpython-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.c | 22 |
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 */ |