From f9afb39a7cc07490aae204824d1459030f456612 Mon Sep 17 00:00:00 2001 From: Tomas Roun Date: Wed, 7 Jan 2026 23:58:04 +0100 Subject: [PATCH 1/5] Fix crash when seeking a closed BufferedWriter --- Lib/test/test_io/test_bufferedio.py | 11 +++++++++++ Modules/_io/bufferedio.c | 4 ++++ 2 files changed, 15 insertions(+) diff --git a/Lib/test/test_io/test_bufferedio.py b/Lib/test/test_io/test_bufferedio.py index 3278665bdc9dd3..f77cd759ed8229 100644 --- a/Lib/test/test_io/test_bufferedio.py +++ b/Lib/test/test_io/test_bufferedio.py @@ -983,6 +983,17 @@ def closed(self): self.assertRaisesRegex(ValueError, "test", bufio.flush) self.assertRaisesRegex(ValueError, "test", bufio.close) + def test_gh_143375(self): + bufio = self.tp(self.MockRawIO()) + + class EvilIndex: + def __index__(self): + bufio.close() + return 0 + + with self.assertRaisesRegex(ValueError, "seek of closed file"): + bufio.seek(EvilIndex()) + class PyBufferedWriterTest(BufferedWriterTest, PyTestCase): tp = pyio.BufferedWriter diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index 4602f2b42a6017..65dfaafc7f43ef 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -1393,6 +1393,10 @@ _io__Buffered_seek_impl(buffered *self, PyObject *targetobj, int whence) if (target == -1 && PyErr_Occurred()) return NULL; + // PyNumber_AsOff_t calls user code via __index__, which + // could have closed the file. + CHECK_CLOSED(self, "seek of closed file") + /* SEEK_SET and SEEK_CUR are special because we could seek inside the buffer. Other whence values must be managed without this optimization. Some Operating Systems can provide additional values, like From 039bf4151ed411c2520ff63eede8c6b102ef10c3 Mon Sep 17 00:00:00 2001 From: Tomas Roun Date: Thu, 8 Jan 2026 19:56:47 +0100 Subject: [PATCH 2/5] Add news entry --- .../2026-01-08-19-56-40.gh-issue-143375.QCzA_8.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-01-08-19-56-40.gh-issue-143375.QCzA_8.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-08-19-56-40.gh-issue-143375.QCzA_8.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-01-08-19-56-40.gh-issue-143375.QCzA_8.rst new file mode 100644 index 00000000000000..cc710d97740228 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-01-08-19-56-40.gh-issue-143375.QCzA_8.rst @@ -0,0 +1,2 @@ +Fix a crash in :meth:`~io.BufferedWriter.seek` when passing an object with a +specially crafted :meth:`~object.__index__`. From 2ae393b05a681132bc72e5117f530eda8537c4f7 Mon Sep 17 00:00:00 2001 From: Tomas Roun Date: Thu, 8 Jan 2026 21:59:31 +0100 Subject: [PATCH 3/5] Try with a :func: --- .../2026-01-08-19-56-40.gh-issue-143375.QCzA_8.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-08-19-56-40.gh-issue-143375.QCzA_8.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-01-08-19-56-40.gh-issue-143375.QCzA_8.rst index cc710d97740228..fa4306d230ecc5 100644 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-08-19-56-40.gh-issue-143375.QCzA_8.rst +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-01-08-19-56-40.gh-issue-143375.QCzA_8.rst @@ -1,2 +1,2 @@ -Fix a crash in :meth:`~io.BufferedWriter.seek` when passing an object with a +Fix a crash in :func:`~io.BufferedWriter.seek` when passing an object with a specially crafted :meth:`~object.__index__`. From d0c7ff5e6c62eb767bf3aa03b6ed5aaa1d896658 Mon Sep 17 00:00:00 2001 From: Tomas Roun Date: Thu, 8 Jan 2026 22:00:23 +0100 Subject: [PATCH 4/5] Move news entry to Library --- .../2026-01-08-19-56-40.gh-issue-143375.QCzA_8.rst | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Misc/NEWS.d/next/{Core_and_Builtins => Library}/2026-01-08-19-56-40.gh-issue-143375.QCzA_8.rst (100%) diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-08-19-56-40.gh-issue-143375.QCzA_8.rst b/Misc/NEWS.d/next/Library/2026-01-08-19-56-40.gh-issue-143375.QCzA_8.rst similarity index 100% rename from Misc/NEWS.d/next/Core_and_Builtins/2026-01-08-19-56-40.gh-issue-143375.QCzA_8.rst rename to Misc/NEWS.d/next/Library/2026-01-08-19-56-40.gh-issue-143375.QCzA_8.rst From f72095014be6984bc9ea25ae1be1b585f02d0b1c Mon Sep 17 00:00:00 2001 From: Tomas Roun Date: Thu, 8 Jan 2026 22:15:11 +0100 Subject: [PATCH 5/5] Fix news entry --- .../Library/2026-01-08-19-56-40.gh-issue-143375.QCzA_8.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Misc/NEWS.d/next/Library/2026-01-08-19-56-40.gh-issue-143375.QCzA_8.rst b/Misc/NEWS.d/next/Library/2026-01-08-19-56-40.gh-issue-143375.QCzA_8.rst index fa4306d230ecc5..697343c7e8fa6a 100644 --- a/Misc/NEWS.d/next/Library/2026-01-08-19-56-40.gh-issue-143375.QCzA_8.rst +++ b/Misc/NEWS.d/next/Library/2026-01-08-19-56-40.gh-issue-143375.QCzA_8.rst @@ -1,2 +1,2 @@ -Fix a crash in :func:`~io.BufferedWriter.seek` when passing an object with a -specially crafted :meth:`~object.__index__`. +Fix a crash in the ``seek`` method of :class:`~io.BufferedWriter` when +passing an object with a specially crafted :meth:`~object.__index__`.