aboutsummaryrefslogtreecommitdiff
path: root/paramiko/file.py
diff options
context:
space:
mode:
Diffstat (limited to 'paramiko/file.py')
-rw-r--r--paramiko/file.py16
1 files changed, 12 insertions, 4 deletions
diff --git a/paramiko/file.py b/paramiko/file.py
index 311e198..e3b0a16 100644
--- a/paramiko/file.py
+++ b/paramiko/file.py
@@ -206,6 +206,7 @@ class BufferedFile (ClosingContextManager):
if not (self._flags & self.FLAG_READ):
raise IOError('File not open for reading')
line = self._rbuffer
+ 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
@@ -220,11 +221,11 @@ class BufferedFile (ClosingContextManager):
# enough.
if (size is not None) and (size >= 0):
if len(line) >= size:
- # truncate line and return
+ # truncate line
self._rbuffer = line[size:]
line = line[:size]
- self._pos += len(line)
- return line if self._flags & self.FLAG_BINARY else u(line)
+ truncated = True
+ break
n = size - len(line)
else:
n = self._bufsize
@@ -246,10 +247,17 @@ class BufferedFile (ClosingContextManager):
rpos = line.find(cr_byte)
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
- self._rbuffer = line[xpos:]
+ # 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
if (len(self._rbuffer) == 0) and (lf == cr_byte):