Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 32ca3dc

Browse files
Issue #23099: Closing io.BytesIO with exported buffer is rejected now to
prevent corrupting exported buffer.
2 parents 7a27c97 + c057c38 commit 32ca3dc

5 files changed

Lines changed: 23 additions & 7 deletions

File tree

Doc/library/io.rst

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -578,7 +578,8 @@ than raw I/O does.
578578
.. class:: BytesIO([initial_bytes])
579579

580580
A stream implementation using an in-memory bytes buffer. It inherits
581-
:class:`BufferedIOBase`.
581+
:class:`BufferedIOBase`. The buffer is discarded when the
582+
:meth:`~IOBase.close` method is called.
582583

583584
The argument *initial_bytes* contains optional initial :class:`bytes` data.
584585

@@ -599,14 +600,15 @@ than raw I/O does.
599600

600601
.. note::
601602
As long as the view exists, the :class:`BytesIO` object cannot be
602-
resized.
603+
resized or closed.
603604

604605
.. versionadded:: 3.2
605606

606607
.. method:: getvalue()
607608

608609
Return :class:`bytes` containing the entire contents of the buffer.
609610

611+
610612
.. method:: read1()
611613

612614
In :class:`BytesIO`, this is the same as :meth:`read`.
@@ -880,7 +882,8 @@ Text I/O
880882

881883
.. class:: StringIO(initial_value='', newline='\\n')
882884

883-
An in-memory stream for text I/O.
885+
An in-memory stream for text I/O. The text buffer is discarded when the
886+
:meth:`~IOBase.close` method is called.
884887

885888
The initial value of the buffer (an empty string by default) can be set by
886889
providing *initial_value*. The *newline* argument works like that of
@@ -892,9 +895,7 @@ Text I/O
892895

893896
.. method:: getvalue()
894897

895-
Return a ``str`` containing the entire contents of the buffer at any
896-
time before the :class:`StringIO` object's :meth:`close` method is
897-
called.
898+
Return a ``str`` containing the entire contents of the buffer.
898899

899900
Example usage::
900901

Lib/_pyio.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -852,8 +852,14 @@ def getvalue(self):
852852
def getbuffer(self):
853853
"""Return a readable and writable view of the buffer.
854854
"""
855+
if self.closed:
856+
raise ValueError("getbuffer on closed file")
855857
return memoryview(self._buffer)
856858

859+
def close(self):
860+
self._buffer.clear()
861+
super().close()
862+
857863
def read(self, size=None):
858864
if self.closed:
859865
raise ValueError("read from closed file")

Lib/test/test_memoryio.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,14 +399,19 @@ def test_getbuffer(self):
399399
# raises a BufferError.
400400
self.assertRaises(BufferError, memio.write, b'x' * 100)
401401
self.assertRaises(BufferError, memio.truncate)
402+
self.assertRaises(BufferError, memio.close)
403+
self.assertFalse(memio.closed)
402404
# Mutating the buffer updates the BytesIO
403405
buf[3:6] = b"abc"
404406
self.assertEqual(bytes(buf), b"123abc7890")
405407
self.assertEqual(memio.getvalue(), b"123abc7890")
406-
# After the buffer gets released, we can resize the BytesIO again
408+
# After the buffer gets released, we can resize and close the BytesIO
409+
# again
407410
del buf
408411
support.gc_collect()
409412
memio.truncate()
413+
memio.close()
414+
self.assertRaises(ValueError, memio.getbuffer)
410415

411416

412417
class PyBytesIOTest(MemoryTestMixin, MemorySeekTestMixin,

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,9 @@ Core and Builtins
232232
Library
233233
-------
234234

235+
- Issue #23099: Closing io.BytesIO with exported buffer is rejected now to
236+
prevent corrupting exported buffer.
237+
235238
- Issue #23326: Removed __ne__ implementations. Since fixing default __ne__
236239
implementation in issue #21408 they are redundant.
237240

Modules/_io/bytesio.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -779,6 +779,7 @@ PyDoc_STRVAR(close_doc,
779779
static PyObject *
780780
bytesio_close(bytesio *self)
781781
{
782+
CHECK_EXPORTS(self);
782783
reset(self);
783784
Py_RETURN_NONE;
784785
}

0 commit comments

Comments
 (0)