summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--paramiko/file.py7
-rwxr-xr-xtests/test_file.py9
2 files changed, 10 insertions, 6 deletions
diff --git a/paramiko/file.py b/paramiko/file.py
index f549cb99..1c99abeb 100644
--- a/paramiko/file.py
+++ b/paramiko/file.py
@@ -204,7 +204,7 @@ class BufferedFile (object):
if not (self._flags & self.FLAG_READ):
raise IOError('File not open for reading')
line = self._rbuffer
- truncated = False;
+ truncated = False
while True:
if self._at_trailing_cr and (self._flags & self.FLAG_UNIVERSAL_NEWLINE) and (len(line) > 0):
# edge case: the newline may be '\r\n' and we may have read
@@ -246,12 +246,15 @@ class BufferedFile (object):
if (rpos >= 0) and (rpos < pos or pos < 0):
pos = rpos
if pos == -1:
+ # we couldn't find a newline in the truncated string, return it
self._pos += len(line)
return line if self._flags & self.FLAG_BINARY else u(line)
xpos = pos + 1
if (line[pos] == cr_byte_value) and (xpos < len(line)) and (line[xpos] == linefeed_byte_value):
xpos += 1
-
+ # if the string was truncated, _rbuffer needs to have the string after
+ # the newline character plus the truncated part of the line we stored
+ # earlier in _rbuffer
self._rbuffer = line[xpos:] + self._rbuffer if truncated else line[xpos:]
lf = line[pos:xpos]
line = line[:pos] + linefeed_byte
diff --git a/tests/test_file.py b/tests/test_file.py
index 044dc591..a6ff69e9 100755
--- a/tests/test_file.py
+++ b/tests/test_file.py
@@ -70,16 +70,17 @@ class BufferedFileTest (unittest.TestCase):
def test_2_readline(self):
f = LoopbackFile('r+U')
- f.write(b'First line.\nSecond line.\r\nThird line.\nFourth line.\nFifth line.\nFinal line non-terminated.')
+ f.write(b'First line.\nSecond line.\r\nThird line.\n' +
+ b'Fourth line.\nFinal line non-terminated.')
+
self.assertEqual(f.readline(), 'First line.\n')
# universal newline mode should convert this linefeed:
self.assertEqual(f.readline(), 'Second line.\n')
# truncated line:
self.assertEqual(f.readline(7), 'Third l')
self.assertEqual(f.readline(), 'ine.\n')
- # readline should not read past the fourth line
- self.assertEqual(f.readline(25), 'Fourth line.\n')
- self.assertEqual(f.readline(), 'Fifth line.\n')
+ # newline should be detected and only the fourth line returned
+ self.assertEqual(f.readline(39), 'Fourth line.\n')
self.assertEqual(f.readline(), 'Final line non-terminated.')
self.assertEqual(f.readline(), '')
f.close()