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]

Reply via email to