Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Seek Operations in SftpFileStream #910

Merged
merged 7 commits into from
Nov 29, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,6 @@ project.lock.json

# Build outputs
build/target/

# Visual Studio cache/options directory
.vs/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add leading forward slash since this ignore only applies to the root directory of the repo.

59 changes: 19 additions & 40 deletions src/Renci.SshNet/Sftp/SftpFileStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -788,26 +788,6 @@ public override long Seek(long offset, SeekOrigin origin)
{
// Flush the write buffer and then seek.
FlushWriteBuffer();

switch (origin)
{
case SeekOrigin.Begin:
newPosn = offset;
break;
case SeekOrigin.Current:
newPosn = _position + offset;
break;
case SeekOrigin.End:
var attributes = _session.RequestFStat(_handle, false);
newPosn = attributes.Size - offset;
break;
}

if (newPosn == -1)
{
throw new EndOfStreamException("End of stream.");
}
_position = newPosn;
}
else
{
Expand Down Expand Up @@ -838,29 +818,28 @@ public override long Seek(long offset, SeekOrigin origin)
// Abandon the read buffer.
_bufferPosition = 0;
_bufferLen = 0;
}

// Seek to the new position.
switch (origin)
{
case SeekOrigin.Begin:
newPosn = offset;
break;
case SeekOrigin.Current:
newPosn = _position + offset;
break;
case SeekOrigin.End:
var attributes = _session.RequestFStat(_handle, false);
newPosn = attributes.Size - offset;
break;
}

if (newPosn < 0)
{
throw new EndOfStreamException();
}
// Seek to the new position.
switch (origin)
{
case SeekOrigin.Begin:
newPosn = offset;
break;
case SeekOrigin.Current:
newPosn = _position + offset;
break;
case SeekOrigin.End:
var attributes = _session.RequestFStat(_handle, false);
newPosn = attributes.Size + offset;
break;
}

_position = newPosn;
if (newPosn < 0)
{
throw new EndOfStreamException("End of stream.");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are providing a non-default exception message, causing the test SeekShouldHaveThrownEndOfStreamException to fail. I beleive if you just use throw new EndOfStreamException(); this will be fixed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for pointing that out. The exception message is already present in another part of the code, so I assumed I should leave it in there.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@drieseng There have been suggestions in other issues that we should localize exception messages. While that is probably too much work at this time, I propose to use default exception messages where possible and to stop checking error messages in the tests and rely on only asserting exception type (and other structured info in the exception) in the tests. Do you agree?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have noticed that the exception message format is different across .NET versions. For example:
.NET Framework 3.5

ArgumentException error message.
Parameter name: ParamName

.NET Core 3.0

ArgumentException error message. (Parameter 'ParamName')

This causes some tests to pass on one framework and fail on another.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@IgorMilavec, in general I prefer very specific asserts. To be honest, I think we have more important stuff to deal with than localization. But I'm ok to discuss this as a team, and decide where we want to go with this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@LemonPi314, that's indeed something I was already aware of and which I dealt with in other (professional) projects.

}
_position = newPosn;
return _position;
}
}
Expand Down