mirror of
https://github.com/python/cpython.git
synced 2025-08-15 22:30:42 +00:00
[3.12] gh-111174: Fix crash in getbuffer() called repeatedly for empty BytesIO (GH-111210) (GH-111314)
(cherry picked from commit 9da98c0d9a
)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
This commit is contained in:
parent
5e94556f83
commit
45c0b38880
3 changed files with 20 additions and 3 deletions
|
@ -463,6 +463,20 @@ class PyBytesIOTest(MemoryTestMixin, MemorySeekTestMixin, unittest.TestCase):
|
||||||
memio.close()
|
memio.close()
|
||||||
self.assertRaises(ValueError, memio.getbuffer)
|
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):
|
def test_read1(self):
|
||||||
buf = self.buftype("1234567890")
|
buf = self.buftype("1234567890")
|
||||||
self.assertEqual(self.ioclass(buf).read1(), buf)
|
self.assertEqual(self.ioclass(buf).read1(), buf)
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Fix crash in :meth:`io.BytesIO.getbuffer` called repeatedly for empty
|
||||||
|
BytesIO.
|
|
@ -124,12 +124,13 @@ unshare_buffer(bytesio *self, size_t size)
|
||||||
static int
|
static int
|
||||||
resize_buffer(bytesio *self, size_t size)
|
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
|
/* Here, unsigned types are used to avoid dealing with signed integer
|
||||||
overflow, which is undefined in C. */
|
overflow, which is undefined in C. */
|
||||||
size_t alloc = PyBytes_GET_SIZE(self->buf);
|
size_t alloc = PyBytes_GET_SIZE(self->buf);
|
||||||
|
|
||||||
assert(self->buf != NULL);
|
|
||||||
|
|
||||||
/* For simplicity, stay in the range of the signed type. Anyway, Python
|
/* For simplicity, stay in the range of the signed type. Anyway, Python
|
||||||
doesn't allow strings to be longer than this. */
|
doesn't allow strings to be longer than this. */
|
||||||
if (size > PY_SSIZE_T_MAX)
|
if (size > PY_SSIZE_T_MAX)
|
||||||
|
@ -1072,7 +1073,7 @@ bytesiobuf_getbuffer(bytesiobuf *obj, Py_buffer *view, int flags)
|
||||||
"bytesiobuf_getbuffer: view==NULL argument is obsolete");
|
"bytesiobuf_getbuffer: view==NULL argument is obsolete");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (SHARED_BUF(b)) {
|
if (b->exports == 0 && SHARED_BUF(b)) {
|
||||||
if (unshare_buffer(b, b->string_size) < 0)
|
if (unshare_buffer(b, b->string_size) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue