mirror of
https://github.com/python/cpython.git
synced 2026-10-28 10:25:05 +08:00
gh-159739: Respect readline limits after a short read (#159974)
Backport to 3.15 and 3.14. Both branches use a bytearray instead of PyBytesWriter; the test lives in Lib/test/test_io.py on 3.14.
This commit is contained in:
1 parent
d36a3f6970
commit
87eaef1171
4 files changed
+21
-2
No files matched your search
+1
-1
@@ -528,7 +528,7 @@ class IOBase(metaclass=abc.ABCMeta):
|
||||
return 1
|
||||
n = (readahead.find(b"\n") + 1) or len(readahead)
|
||||
if size >= 0:
|
||||
n = min(n, size)
|
||||
n = min(n, size - len(res))
|
||||
return n
|
||||
else:
|
||||
def nreadahead():
|
||||
|
||||
@@ -319,6 +319,22 @@ class IOTest:
|
||||
with self.open(os_helper.TESTFN, "r", encoding="utf-8") as f:
|
||||
self.assertRaises(TypeError, f.readline, 5.3)
|
||||
|
||||
def test_readline_limit_with_short_read(self):
|
||||
class Reader(self.IOBase):
|
||||
data = b"abcdef"
|
||||
|
||||
def peek(self, size):
|
||||
return self.data
|
||||
|
||||
def read(self, size):
|
||||
data = self.data[:min(size, 2)]
|
||||
self.data = self.data[len(data):]
|
||||
return data
|
||||
|
||||
reader = Reader()
|
||||
self.assertEqual(reader.readline(3), b"abc")
|
||||
self.assertEqual(reader.data, b"def")
|
||||
|
||||
def test_readline_nonsizeable(self):
|
||||
# Issue #30061
|
||||
# Crash when readline() returns an object without __len__
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
Fix :meth:`io.IOBase.readline` returning more bytes than requested when a
|
||||
stream supports :meth:`!peek` and returns short reads.
|
||||
@@ -653,8 +653,9 @@ _io__IOBase_readline_impl(PyObject *self, Py_ssize_t limit)
|
||||
Py_ssize_t n = 0;
|
||||
const char *buf = PyBytes_AS_STRING(readahead);
|
||||
if (limit >= 0) {
|
||||
Py_ssize_t remaining = limit - PyBytesWriter_GetSize(writer);
|
||||
do {
|
||||
if (n >= PyBytes_GET_SIZE(readahead) || n >= limit)
|
||||
if (n >= PyBytes_GET_SIZE(readahead) || n >= remaining)
|
||||
break;
|
||||
if (buf[n++] == '\n')
|
||||
break;
|
||||
|
||||
Reference in new issue
Block a user