https://github.com/python/cpython/commit/daccca0a46e9943f248e5f6c0a0dafe2125fd7c8 commit: daccca0a46e9943f248e5f6c0a0dafe2125fd7c8 branch: 3.14 author: Miss Islington (bot) <[email protected]> committer: StanFromIreland <[email protected]> date: 2026-10-29T14:26:10Z summary:
[3.14] gh-160781: Fix `BytesIO` overflow handling for large sizes (GH-160783) (#160892) (cherry picked from commit 7b727ab601347a83e0a173a708aaa7018c9158aa) Co-authored-by: Cody Maloney <[email protected]> files: A Misc/NEWS.d/next/Library/2026-10-27-15-26-53.gh-issue-160781.4VSeQK.rst A Misc/NEWS.d/next/Library/2026-10-27-15-42-16.gh-issue-160781.VGLB9S.rst M Lib/test/test_memoryio.py M Modules/_io/bytesio.c diff --git a/Lib/test/test_memoryio.py b/Lib/test/test_memoryio.py index 7e9666fa9746bfe..967e2390a8a7ee4 100644 --- a/Lib/test/test_memoryio.py +++ b/Lib/test/test_memoryio.py @@ -565,6 +565,10 @@ def test_issue141311(self): self.assertEqual(sys.maxsize, memio.seek(sys.maxsize)) buf = bytearray(2) self.assertEqual(0, memio.readinto(buf)) + # Writing there must not overflow the buffer size. + memio.seek(sys.maxsize - 1) + self.assertRaises((MemoryError, OverflowError), memio.write, b"x") + self.assertEqual(memio.getvalue(), b"") def test_unicode(self): memio = self.ioclass() @@ -882,6 +886,12 @@ def __index__(self): finally: size.result.release() + # Sizes above 2**31 - 1 must work where C long is 32-bit. + if sys.maxsize > 2**31: + stream = self.ioclass(b'abc') + self.assertEqual(stream.truncate(2**31), 2**31) + self.assertEqual(stream.getvalue(), b'abc') + def test_readinto_overlapping_buffer(self): with self.ioclass(b'abcd') as stream: with stream.getbuffer()[1:] as target: diff --git a/Misc/NEWS.d/next/Library/2026-10-27-15-26-53.gh-issue-160781.4VSeQK.rst b/Misc/NEWS.d/next/Library/2026-10-27-15-26-53.gh-issue-160781.4VSeQK.rst new file mode 100644 index 000000000000000..f6463a5d5313690 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-10-27-15-26-53.gh-issue-160781.4VSeQK.rst @@ -0,0 +1,3 @@ +Fix :class:`io.BytesIO` raising :exc:`SystemError` instead of +:exc:`OverflowError` when writing at a position close to +:data:`sys.maxsize`. diff --git a/Misc/NEWS.d/next/Library/2026-10-27-15-42-16.gh-issue-160781.VGLB9S.rst b/Misc/NEWS.d/next/Library/2026-10-27-15-42-16.gh-issue-160781.VGLB9S.rst new file mode 100644 index 000000000000000..73c8c177fc88282 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-10-27-15-42-16.gh-issue-160781.VGLB9S.rst @@ -0,0 +1,2 @@ +Fix :class:`io.BytesIO` implementation of :meth:`io.IOBase.truncate` rejecting +sizes larger than ``2**31 - 1`` on Windows. diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c index 175a5d280d72b07..f6b74f470a2b876 100644 --- a/Modules/_io/bytesio.c +++ b/Modules/_io/bytesio.c @@ -210,6 +210,9 @@ resize_buffer_lock_held(bytesio *self, size_t size) /* Major upsize; resize up to exact size */ alloc = size + 1; } + if (alloc > PY_SSIZE_T_MAX) { + goto overflow; + } if (SHARED_BUF(self)) { if (unshare_buffer_lock_held(self, alloc) < 0) @@ -701,7 +704,7 @@ _io_BytesIO_truncate_impl(bytesio *self, PyObject *size) new_size = self->pos; } else { - new_size = PyLong_AsLong(size); + new_size = PyNumber_AsSsize_t(size, PyExc_OverflowError); if (new_size == -1 && PyErr_Occurred()) { return NULL; } _______________________________________________ Python-checkins mailing list -- [email protected] To unsubscribe send an email to [email protected] https://mail.python.org/mailman3//lists/python-checkins.python.org Member address: [email protected]
