]> granicus.if.org Git - python/commitdiff
Issue #23099: Closing io.BytesIO with exported buffer is rejected now to
authorSerhiy Storchaka <storchaka@gmail.com>
Tue, 3 Feb 2015 00:00:18 +0000 (02:00 +0200)
committerSerhiy Storchaka <storchaka@gmail.com>
Tue, 3 Feb 2015 00:00:18 +0000 (02:00 +0200)
prevent corrupting exported buffer.

Doc/library/io.rst
Lib/_pyio.py
Lib/test/test_memoryio.py
Misc/NEWS
Modules/_io/bytesio.c

index b8dc688a6307fa1e7ef2401abf6217f3463bf43f..3adf6e9c33e5c0dcd4cb535b5318594840c37d3f 100644 (file)
@@ -563,7 +563,8 @@ than raw I/O does.
 .. class:: BytesIO([initial_bytes])
 
    A stream implementation using an in-memory bytes buffer.  It inherits
-   :class:`BufferedIOBase`.
+   :class:`BufferedIOBase`.  The buffer is discarded when the
+   :meth:`~IOBase.close` method is called.
 
    The argument *initial_bytes* contains optional initial :class:`bytes` data.
 
@@ -584,7 +585,7 @@ than raw I/O does.
 
       .. note::
          As long as the view exists, the :class:`BytesIO` object cannot be
-         resized.
+         resized or closed.
 
       .. versionadded:: 3.2
 
@@ -592,6 +593,7 @@ than raw I/O does.
 
       Return :class:`bytes` containing the entire contents of the buffer.
 
+
    .. method:: read1()
 
       In :class:`BytesIO`, this is the same as :meth:`read`.
@@ -858,7 +860,8 @@ Text I/O
 
 .. class:: StringIO(initial_value='', newline='\\n')
 
-   An in-memory stream for text I/O.
+   An in-memory stream for text I/O.  The text buffer is discarded when the
+   :meth:`~IOBase.close` method is called.
 
    The initial value of the buffer (an empty string by default) can be set by
    providing *initial_value*.  The *newline* argument works like that of
@@ -870,9 +873,7 @@ Text I/O
 
    .. method:: getvalue()
 
-      Return a ``str`` containing the entire contents of the buffer at any
-      time before the :class:`StringIO` object's :meth:`close` method is
-      called.
+      Return a ``str`` containing the entire contents of the buffer.
 
    Example usage::
 
index 01683f8285945e12911d0e7e4b20c17b728b6c08..577b6003b5978a311f467cc1b384f78a9682293e 100644 (file)
@@ -833,8 +833,14 @@ class BytesIO(BufferedIOBase):
     def getbuffer(self):
         """Return a readable and writable view of the buffer.
         """
+        if self.closed:
+            raise ValueError("getbuffer on closed file")
         return memoryview(self._buffer)
 
+    def close(self):
+        self._buffer.clear()
+        super().close()
+
     def read(self, size=None):
         if self.closed:
             raise ValueError("read from closed file")
index 7cae8b2965323b64011b6f62c7b5263eacc05c7a..9a2461dea68b83b435c0b7b45941956c61938d5c 100644 (file)
@@ -398,14 +398,19 @@ class BytesIOMixin:
         # raises a BufferError.
         self.assertRaises(BufferError, memio.write, b'x' * 100)
         self.assertRaises(BufferError, memio.truncate)
+        self.assertRaises(BufferError, memio.close)
+        self.assertFalse(memio.closed)
         # Mutating the buffer updates the BytesIO
         buf[3:6] = b"abc"
         self.assertEqual(bytes(buf), b"123abc7890")
         self.assertEqual(memio.getvalue(), b"123abc7890")
-        # After the buffer gets released, we can resize the BytesIO again
+        # After the buffer gets released, we can resize and close the BytesIO
+        # again
         del buf
         support.gc_collect()
         memio.truncate()
+        memio.close()
+        self.assertRaises(ValueError, memio.getbuffer)
 
 
 class PyBytesIOTest(MemoryTestMixin, MemorySeekTestMixin,
index 976368ef797cf743dfed0b7c84082a4fcedf4e20..6d58e8b8658c30c6455b38dee3b60da8e16d5e5e 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -56,6 +56,9 @@ Core and Builtins
 Library
 -------
 
+- Issue #23099: Closing io.BytesIO with exported buffer is rejected now to
+  prevent corrupting exported buffer.
+
 - Issue #23363: Fix possible overflow in itertools.permutations.
 
 - Issue #23364: Fix possible overflow in itertools.product.
index 57c207341cecfd2042495e0b54a6d3a1dc8f06dc..1537d979a31daa62b0ad01bedd8fb6f55332b6ed 100644 (file)
@@ -657,6 +657,7 @@ PyDoc_STRVAR(close_doc,
 static PyObject *
 bytesio_close(bytesio *self)
 {
+    CHECK_EXPORTS(self);
     if (self->buf != NULL) {
         PyMem_Free(self->buf);
         self->buf = NULL;