summaryrefslogtreecommitdiffstats
path: root/Modules/clinic
diff options
context:
space:
mode:
authorGregory P. Smith <greg@krypto.org>2022-03-20 19:28:15 (GMT)
committerGitHub <noreply@github.com>2022-03-20 19:28:15 (GMT)
commit9d1c4d69dbc800ac344565119337fcf490cdc800 (patch)
treef27ebdb3ae2bfa27853b42def2df6f29625ac5df /Modules/clinic
parent3ae975f1ac880c47d51cca6c9e305547bd365be7 (diff)
downloadcpython-9d1c4d69dbc800ac344565119337fcf490cdc800.zip
cpython-9d1c4d69dbc800ac344565119337fcf490cdc800.tar.gz
cpython-9d1c4d69dbc800ac344565119337fcf490cdc800.tar.bz2
bpo-38256: Fix binascii.crc32() when inputs are 4+GiB (GH-32000)
When compiled with `USE_ZLIB_CRC32` defined (`configure` sets this on POSIX systems), `binascii.crc32(...)` failed to compute the correct value when the input data was >= 4GiB. Because the zlib crc32 API is limited to a 32-bit length. This lines it up with the `zlib.crc32(...)` implementation that doesn't have that flaw. **Performance:** This also adopts the same GIL releasing for larger inputs logic that `zlib.crc32` has, and causes the Windows build to always use zlib's crc32 instead of our slow C code as zlib is a required build dependency on Windows.
Diffstat (limited to 'Modules/clinic')
-rw-r--r--Modules/clinic/zlibmodule.c.h11
1 files changed, 8 insertions, 3 deletions
diff --git a/Modules/clinic/zlibmodule.c.h b/Modules/clinic/zlibmodule.c.h
index e2a5fcc..71136d3 100644
--- a/Modules/clinic/zlibmodule.c.h
+++ b/Modules/clinic/zlibmodule.c.h
@@ -753,7 +753,7 @@ PyDoc_STRVAR(zlib_crc32__doc__,
#define ZLIB_CRC32_METHODDEF \
{"crc32", (PyCFunction)(void(*)(void))zlib_crc32, METH_FASTCALL, zlib_crc32__doc__},
-static PyObject *
+static unsigned int
zlib_crc32_impl(PyObject *module, Py_buffer *data, unsigned int value);
static PyObject *
@@ -762,6 +762,7 @@ zlib_crc32(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
PyObject *return_value = NULL;
Py_buffer data = {NULL, NULL};
unsigned int value = 0;
+ unsigned int _return_value;
if (!_PyArg_CheckPositional("crc32", nargs, 1, 2)) {
goto exit;
@@ -781,7 +782,11 @@ zlib_crc32(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
goto exit;
}
skip_optional:
- return_value = zlib_crc32_impl(module, &data, value);
+ _return_value = zlib_crc32_impl(module, &data, value);
+ if ((_return_value == (unsigned int)-1) && PyErr_Occurred()) {
+ goto exit;
+ }
+ return_value = PyLong_FromUnsignedLong((unsigned long)_return_value);
exit:
/* Cleanup for data */
@@ -815,4 +820,4 @@ exit:
#ifndef ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF
#define ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF
#endif /* !defined(ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF) */
-/*[clinic end generated code: output=e3e8a6142ea045a7 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=f009d194565416d1 input=a9049054013a1b77]*/