diff --git a/Lib/shutil.py b/Lib/shutil.py index 5c1255a6713de6..1e89256cc34443 100644 --- a/Lib/shutil.py +++ b/Lib/shutil.py @@ -135,9 +135,13 @@ def _fastcopy_sendfile(fsrc, fdst): # should not make any difference, also in case the file content # changes while being copied. try: - blocksize = max(os.fstat(infd).st_size, 2 ** 23) # min 8MB - except Exception: - blocksize = 2 ** 27 # 128MB + blocksize = max(os.fstat(infd).st_size, 2 ** 23) # min 8MiB + except OSError: + blocksize = 2 ** 27 # 128MiB + # On 32-bit architectures truncate to 1GiB to avoid OverflowError, + # see bpo-38319. + if sys.maxsize < 2 ** 32: + blocksize = min(blocksize, 2 ** 30) offset = 0 while True: diff --git a/Lib/socket.py b/Lib/socket.py index af2ed0e76a4981..813f4ef5c3e1f5 100644 --- a/Lib/socket.py +++ b/Lib/socket.py @@ -355,8 +355,8 @@ def _sendfile_use_sendfile(self, file, offset=0, count=None): raise _GiveupOnSendfile(err) # not a regular file if not fsize: return 0 # empty file - blocksize = fsize if not count else count - + # Truncate to 1GiB to avoid OverflowError, see bpo-38319. + blocksize = min(count or fsize, 2 ** 30) timeout = self.gettimeout() if timeout == 0: raise ValueError("non-blocking sockets are not supported") diff --git a/Misc/NEWS.d/next/Library/2019-09-30-22-06-33.bpo-38319.5QjiDa.rst b/Misc/NEWS.d/next/Library/2019-09-30-22-06-33.bpo-38319.5QjiDa.rst new file mode 100644 index 00000000000000..376a9e459de27c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-09-30-22-06-33.bpo-38319.5QjiDa.rst @@ -0,0 +1,2 @@ +sendfile() used in socket and shutil modules was raising OverflowError for +files >= 2GiB on 32-bit architectures. (patch by Giampaolo Rodola)