Skip to content

Commit 012381c

Browse files
committed
Merge remote-tracking branch 'upstream/3.11' into 3.11
2 parents 4c368bc + be4acc7 commit 012381c

File tree

3 files changed

+30
-10
lines changed

3 files changed

+30
-10
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Workaround a bug in Apple's macOS platform zlib library where
2+
:func:`zlib.crc32` and :func:`binascii.crc32` could produce incorrect results
3+
on multi-gigabyte inputs. Including when using :mod:`zipfile` on zips
4+
containing large data.

Modules/binascii.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -780,12 +780,20 @@ binascii_crc32_impl(PyObject *module, Py_buffer *data, unsigned int crc)
780780

781781
Py_BEGIN_ALLOW_THREADS
782782
/* Avoid truncation of length for very large buffers. crc32() takes
783-
length as an unsigned int, which may be narrower than Py_ssize_t. */
784-
while ((size_t)len > UINT_MAX) {
785-
crc = crc32(crc, buf, UINT_MAX);
786-
buf += (size_t) UINT_MAX;
787-
len -= (size_t) UINT_MAX;
783+
length as an unsigned int, which may be narrower than Py_ssize_t.
784+
We further limit size due to bugs in Apple's macOS zlib.
785+
See https://github.com/python/cpython/issues/105967
786+
*/
787+
#define ZLIB_CRC_CHUNK_SIZE 0x40000000
788+
#if ZLIB_CRC_CHUNK_SIZE > INT_MAX
789+
# error "unsupported less than 32-bit platform?"
790+
#endif
791+
while ((size_t)len > ZLIB_CRC_CHUNK_SIZE) {
792+
crc = crc32(crc, buf, ZLIB_CRC_CHUNK_SIZE);
793+
buf += (size_t) ZLIB_CRC_CHUNK_SIZE;
794+
len -= (size_t) ZLIB_CRC_CHUNK_SIZE;
788795
}
796+
#undef ZLIB_CRC_CHUNK_SIZE
789797
crc = crc32(crc, buf, (unsigned int)len);
790798
Py_END_ALLOW_THREADS
791799
} else {

Modules/zlibmodule.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1444,12 +1444,20 @@ zlib_crc32_impl(PyObject *module, Py_buffer *data, unsigned int value)
14441444

14451445
Py_BEGIN_ALLOW_THREADS
14461446
/* Avoid truncation of length for very large buffers. crc32() takes
1447-
length as an unsigned int, which may be narrower than Py_ssize_t. */
1448-
while ((size_t)len > UINT_MAX) {
1449-
value = crc32(value, buf, UINT_MAX);
1450-
buf += (size_t) UINT_MAX;
1451-
len -= (size_t) UINT_MAX;
1447+
length as an unsigned int, which may be narrower than Py_ssize_t.
1448+
We further limit size due to bugs in Apple's macOS zlib.
1449+
See https://github.com/python/cpython/issues/105967.
1450+
*/
1451+
#define ZLIB_CRC_CHUNK_SIZE 0x40000000
1452+
#if ZLIB_CRC_CHUNK_SIZE > INT_MAX
1453+
# error "unsupported less than 32-bit platform?"
1454+
#endif
1455+
while ((size_t)len > ZLIB_CRC_CHUNK_SIZE) {
1456+
value = crc32(value, buf, ZLIB_CRC_CHUNK_SIZE);
1457+
buf += (size_t) ZLIB_CRC_CHUNK_SIZE;
1458+
len -= (size_t) ZLIB_CRC_CHUNK_SIZE;
14521459
}
1460+
#undef ZLIB_CRC_CHUNK_SIZE
14531461
value = crc32(value, buf, (unsigned int)len);
14541462
Py_END_ALLOW_THREADS
14551463
} else {

0 commit comments

Comments
 (0)