Skip to content

Commit 4e63f7a

Browse files
Issue #24989: Fixed buffer overread in BytesIO.readline() if a position is
set beyond size. Based on patch by John Leitch.
1 parent df6b544 commit 4e63f7a

3 files changed

Lines changed: 21 additions & 1 deletion

File tree

Lib/test/test_memoryio.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,10 @@ def test_read(self):
166166
memio.seek(0)
167167
self.assertEqual(memio.read(None), buf)
168168
self.assertRaises(TypeError, memio.read, '')
169+
memio.seek(len(buf) + 1)
170+
self.assertEqual(memio.read(1), self.EOF)
171+
memio.seek(len(buf) + 1)
172+
self.assertEqual(memio.read(), self.EOF)
169173
memio.close()
170174
self.assertRaises(ValueError, memio.read)
171175

@@ -185,6 +189,9 @@ def test_readline(self):
185189
self.assertEqual(memio.readline(-1), buf)
186190
memio.seek(0)
187191
self.assertEqual(memio.readline(0), self.EOF)
192+
# Issue #24989: Buffer overread
193+
memio.seek(len(buf) * 2 + 1)
194+
self.assertEqual(memio.readline(), self.EOF)
188195

189196
buf = self.buftype("1234567890\n")
190197
memio = self.ioclass((buf * 3)[:-1])
@@ -217,6 +224,9 @@ def test_readlines(self):
217224
memio.seek(0)
218225
self.assertEqual(memio.readlines(None), [buf] * 10)
219226
self.assertRaises(TypeError, memio.readlines, '')
227+
# Issue #24989: Buffer overread
228+
memio.seek(len(buf) * 10 + 1)
229+
self.assertEqual(memio.readlines(), [])
220230
memio.close()
221231
self.assertRaises(ValueError, memio.readlines)
222232

@@ -238,6 +248,9 @@ def test_iterator(self):
238248
self.assertEqual(line, buf)
239249
i += 1
240250
self.assertEqual(i, 10)
251+
# Issue #24989: Buffer overread
252+
memio.seek(len(buf) * 10 + 1)
253+
self.assertEqual(list(memio), [])
241254
memio = self.ioclass(buf * 2)
242255
memio.close()
243256
self.assertRaises(ValueError, memio.__next__)

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ Core and Builtins
1515
Library
1616
-------
1717

18+
- Issue #24989: Fixed buffer overread in BytesIO.readline() if a position is
19+
set beyond size. Based on patch by John Leitch.
20+
1821
- Issue #24913: Fix overrun error in deque.index().
1922
Found by John Leitch and Bryce Darling.
2023

Modules/_io/bytesio.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,18 @@ scan_eol(bytesio *self, Py_ssize_t len)
5757
Py_ssize_t maxlen;
5858

5959
assert(self->buf != NULL);
60+
assert(self->pos >= 0);
61+
62+
if (self->pos >= self->string_size)
63+
return 0;
6064

6165
/* Move to the end of the line, up to the end of the string, s. */
62-
start = PyBytes_AS_STRING(self->buf) + self->pos;
6366
maxlen = self->string_size - self->pos;
6467
if (len < 0 || len > maxlen)
6568
len = maxlen;
6669

6770
if (len) {
71+
start = PyBytes_AS_STRING(self->buf) + self->pos;
6872
n = memchr(start, '\n', len);
6973
if (n)
7074
/* Get the length from the current position to the end of

0 commit comments

Comments
 (0)