diff --git a/src/Renci.SshNet/Sftp/SftpFileStream.cs b/src/Renci.SshNet/Sftp/SftpFileStream.cs index ecb424567..7e91e8a5c 100644 --- a/src/Renci.SshNet/Sftp/SftpFileStream.cs +++ b/src/Renci.SshNet/Sftp/SftpFileStream.cs @@ -6,6 +6,7 @@ #if FEATURE_TAP using System.Threading.Tasks; #endif +using System.Reflection; namespace Renci.SshNet.Sftp { @@ -283,8 +284,8 @@ internal SftpFileStream(ISftpSession session, string path, FileMode mode, FileAc // that ensures we always receive or send the max. number of bytes in a single SSH_FXP_READ // or SSH_FXP_WRITE message - _readBufferSize = (int) session.CalculateOptimalReadLength((uint) bufferSize); - _writeBufferSize = (int) session.CalculateOptimalWriteLength((uint) bufferSize, _handle); + _readBufferSize = (int)session.CalculateOptimalReadLength((uint)bufferSize); + _writeBufferSize = (int)session.CalculateOptimalWriteLength((uint)bufferSize, _handle); if (mode == FileMode.Append) { @@ -381,7 +382,7 @@ internal static async Task OpenAsync(ISftpSession session, strin await session.RequestCloseAsync(handle, cancellationToken).ConfigureAwait(false); } catch - { + { // The original exception is presumably more informative, so we just ignore this one. } throw; @@ -509,7 +510,7 @@ public override int Read(byte[] buffer, int offset, int count) var bytesAvailableInBuffer = _bufferLen - _bufferPosition; if (bytesAvailableInBuffer <= 0) { - var data = _session.RequestRead(_handle, (ulong) _position, (uint) _readBufferSize); + var data = _session.RequestRead(_handle, (ulong)_position, (uint)_readBufferSize); if (data.Length == 0) { @@ -726,7 +727,7 @@ public override int ReadByte() // Read more data into the internal buffer if necessary. if (_bufferPosition >= _bufferLen) { - var data = _session.RequestRead(_handle, (ulong) _position, (uint) _readBufferSize); + var data = _session.RequestRead(_handle, (ulong)_position, (uint)_readBufferSize); if (data.Length == 0) { // We've reached EOF. @@ -783,6 +784,8 @@ public override long Seek(long offset, SeekOrigin origin) return _position; } + var attributes = (SftpFileAttributes)null; + // The behaviour depends upon the read/write mode. if (_bufferOwnedByWrite) { @@ -798,15 +801,16 @@ public override long Seek(long offset, SeekOrigin origin) newPosn = _position + offset; break; case SeekOrigin.End: - var attributes = _session.RequestFStat(_handle, false); - newPosn = attributes.Size - offset; + attributes = _session.RequestFStat(_handle, false); + newPosn = attributes.Size + offset; break; } - if (newPosn == -1) + if (newPosn == -1 || (attributes != null && newPosn > attributes.Size)) { throw new EndOfStreamException("End of stream."); } + _position = newPosn; } else @@ -829,7 +833,7 @@ public override long Seek(long offset, SeekOrigin origin) if (newPosn >= (_position - _bufferPosition) && newPosn < (_position - _bufferPosition + _bufferLen)) { - _bufferPosition = (int) (newPosn - (_position - _bufferPosition)); + _bufferPosition = (int)(newPosn - (_position - _bufferPosition)); _position = newPosn; return _position; } @@ -849,12 +853,16 @@ public override long Seek(long offset, SeekOrigin origin) newPosn = _position + offset; break; case SeekOrigin.End: - var attributes = _session.RequestFStat(_handle, false); - newPosn = attributes.Size - offset; + if (attributes == null) + { + attributes = _session.RequestFStat(_handle, false); + } + + newPosn = attributes.Size + offset; break; } - if (newPosn < 0) + if (newPosn < 0 || (attributes != null && newPosn > attributes.Size)) { throw new EndOfStreamException(); } @@ -974,7 +982,7 @@ public override void Write(byte[] buffer, int offset, int count) { using (var wait = new AutoResetEvent(false)) { - _session.RequestWrite(_handle, (ulong) _position, buffer, offset, tempLen, wait); + _session.RequestWrite(_handle, (ulong)_position, buffer, offset, tempLen, wait); } } else @@ -996,7 +1004,7 @@ public override void Write(byte[] buffer, int offset, int count) { using (var wait = new AutoResetEvent(false)) { - _session.RequestWrite(_handle, (ulong) (_position - _bufferPosition), GetOrCreateWriteBuffer(), 0, _bufferPosition, wait); + _session.RequestWrite(_handle, (ulong)(_position - _bufferPosition), GetOrCreateWriteBuffer(), 0, _bufferPosition, wait); } _bufferPosition = 0; @@ -1106,7 +1114,7 @@ public override void WriteByte(byte value) { using (var wait = new AutoResetEvent(false)) { - _session.RequestWrite(_handle, (ulong) (_position - _bufferPosition), writeBuffer, 0, _bufferPosition, wait); + _session.RequestWrite(_handle, (ulong)(_position - _bufferPosition), writeBuffer, 0, _bufferPosition, wait); } _bufferPosition = 0; @@ -1192,7 +1200,7 @@ private void FlushWriteBuffer() { using (var wait = new AutoResetEvent(false)) { - _session.RequestWrite(_handle, (ulong) (_position - _bufferPosition), _writeBuffer, 0, _bufferPosition, wait); + _session.RequestWrite(_handle, (ulong)(_position - _bufferPosition), _writeBuffer, 0, _bufferPosition, wait); } _bufferPosition = 0;