Skip to content

Commit

Permalink
[3.12] gh-111174: Fix crash in getbuffer() called repeatedly for empt…
Browse files Browse the repository at this point in the history
…y BytesIO (GH-111210) (GH-111314)

(cherry picked from commit 9da98c0)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
  • Loading branch information
miss-islington and serhiy-storchaka committed Oct 25, 2023
1 parent 5e94556 commit 45c0b38
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 3 deletions.
14 changes: 14 additions & 0 deletions Lib/test/test_memoryio.py
Expand Up @@ -463,6 +463,20 @@ def test_getbuffer(self):
memio.close()
self.assertRaises(ValueError, memio.getbuffer)

def test_getbuffer_empty(self):
memio = self.ioclass()
buf = memio.getbuffer()
self.assertEqual(bytes(buf), b"")
# Trying to change the size of the BytesIO while a buffer is exported
# raises a BufferError.
self.assertRaises(BufferError, memio.write, b'x')
buf2 = memio.getbuffer()
self.assertRaises(BufferError, memio.write, b'x')
buf.release()
self.assertRaises(BufferError, memio.write, b'x')
buf2.release()
memio.write(b'x')

def test_read1(self):
buf = self.buftype("1234567890")
self.assertEqual(self.ioclass(buf).read1(), buf)
Expand Down
@@ -0,0 +1,2 @@
Fix crash in :meth:`io.BytesIO.getbuffer` called repeatedly for empty
BytesIO.
7 changes: 4 additions & 3 deletions Modules/_io/bytesio.c
Expand Up @@ -124,12 +124,13 @@ unshare_buffer(bytesio *self, size_t size)
static int
resize_buffer(bytesio *self, size_t size)
{
assert(self->buf != NULL);
assert(self->exports == 0);

/* Here, unsigned types are used to avoid dealing with signed integer
overflow, which is undefined in C. */
size_t alloc = PyBytes_GET_SIZE(self->buf);

assert(self->buf != NULL);

/* For simplicity, stay in the range of the signed type. Anyway, Python
doesn't allow strings to be longer than this. */
if (size > PY_SSIZE_T_MAX)
Expand Down Expand Up @@ -1072,7 +1073,7 @@ bytesiobuf_getbuffer(bytesiobuf *obj, Py_buffer *view, int flags)
"bytesiobuf_getbuffer: view==NULL argument is obsolete");
return -1;
}
if (SHARED_BUF(b)) {
if (b->exports == 0 && SHARED_BUF(b)) {
if (unshare_buffer(b, b->string_size) < 0)
return -1;
}
Expand Down

0 comments on commit 45c0b38

Please sign in to comment.