This commit is contained in:
yihong 2025-12-23 14:13:25 +05:30 committed by GitHub
commit 878d92ab81
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 23 additions and 0 deletions

View file

@ -1560,6 +1560,23 @@ class CTextIOWrapperTest(TextIOWrapperTest, CTestCase):
wrapper = self.TextIOWrapper(raw)
wrapper.close() # should not crash
def test_issue143007(self):
# gh-143007: Null pointer dereference in TextIOWrapper.seek
# via re-entrant __int__
wrapper = self.TextIOWrapper(self.BytesIO(b"x"))
class Cookie(int):
def __new__(cls, wrapper):
obj = int.__new__(cls, 0)
obj.wrapper = wrapper
return obj
def __int__(self):
self.wrapper.detach()
return 0
with self.assertRaises(ValueError):
wrapper.seek(Cookie(wrapper), 0) # should not crash
class PyTextIOWrapperTest(TextIOWrapperTest, PyTestCase):
shutdown_error = "LookupError: unknown encoding: ascii"

View file

@ -0,0 +1,2 @@
Fix crash in :meth:`io.TextIOWrapper.seek` when a custom cookie's
``__int__`` method detaches the underlying buffer.

View file

@ -2644,6 +2644,10 @@ _io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence)
posobj = PyLong_FromOff_t(cookie.start_pos);
if (posobj == NULL)
goto fail;
// gh-143007 PyNumber_Long can call arbitrary code through __int__ which may detach the underlying buffer.
// So we need to re-check that the TextIOWrapper is still attached.
CHECK_ATTACHED(self);
res = PyObject_CallMethodOneArg(self->buffer, &_Py_ID(seek), posobj);
Py_DECREF(posobj);
if (res == NULL)