diff --git a/Modules/zlibmodule.c b/Modules/zlibmodule.c --- a/Modules/zlibmodule.c +++ b/Modules/zlibmodule.c @@ -942,11 +942,24 @@ if (!PyArg_ParseTuple(args, "y*|I:adler32", &pbuf, &adler32val)) return NULL; + /* Releasing the GIL for very small buffers is inefficient and may lower performance */ if (pbuf.len > 1024*5) { + Py_ssize_t len = pbuf.len, rest = 0; Py_BEGIN_ALLOW_THREADS - adler32val = adler32(adler32val, pbuf.buf, pbuf.len); + if ((size_t)len >= UINT_MAX) { + rest = len; + len = UINT_MAX; + } + for (;;) { + adler32val = adler32(adler32val, pbuf.buf, len); + rest -= len; + if (rest <= 0) + break; + if (rest < len) + len = rest; + } Py_END_ALLOW_THREADS } else { adler32val = adler32(adler32val, pbuf.buf, pbuf.len); @@ -970,11 +983,24 @@ if (!PyArg_ParseTuple(args, "y*|I:crc32", &pbuf, &crc32val)) return NULL; + /* Releasing the GIL for very small buffers is inefficient and may lower performance */ if (pbuf.len > 1024*5) { + Py_ssize_t len = pbuf.len, rest = 0; Py_BEGIN_ALLOW_THREADS - signed_val = crc32(crc32val, pbuf.buf, pbuf.len); + if ((size_t)len >= UINT_MAX) { + rest = len; + len = UINT_MAX; + } + for (;;) { + adler32val = crc32(crc32val, pbuf.buf, len); + rest -= len; + if (rest <= 0) + break; + if (rest < len) + len = rest; + } Py_END_ALLOW_THREADS } else { signed_val = crc32(crc32val, pbuf.buf, pbuf.len);