[ 
https://issues.apache.org/jira/browse/SSHD-1181?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Guillaume Nodet reassigned SSHD-1181:
-------------------------------------

    Assignee: Guillaume Nodet

> SFTP Get downloads empty file from servers which supports EOF indication 
> after data
> -----------------------------------------------------------------------------------
>
>                 Key: SSHD-1181
>                 URL: https://issues.apache.org/jira/browse/SSHD-1181
>             Project: MINA SSHD
>          Issue Type: Bug
>    Affects Versions: 2.6.0
>            Reporter: Pavel Pohner
>            Assignee: Guillaume Nodet
>            Priority: Major
>              Labels: SFTP, mina, sshd
>
> So, apparently there's a bug in Mina implementation when downloading the 
> file, which is smaller than Mina's buffer (meaning it gets read in one 
> iteration), from servers, which send EOF indicator at the end of data 
> (https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#[section-9.3|https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-9.3]).
> The bug seems to be in setting up EOF indicator in 
> {noformat}
> org.apache.sshd.sftp.client.impl.SftpInputStreamAsync#pollBuffer{noformat}
> prematurely (one iteration sooner), trace with me this example situation - 
> download of the small file (14 B):
> At some point we arrive to mentioned function _pollBuffer()_, note that 
> _this.pendingReads_ is set to 2. In first call of _pollBuffer()_ we go 
> through this code on receiving SSH_FXP_DATA
> {code:java}
> if (type == SftpConstants.SSH_FXP_DATA) {
>     int dlen = buf.getInt();
>     int rpos = buf.rpos();
>     buf.rpos(rpos + dlen);
>     Boolean b = SftpHelper.getEndOfFileIndicatorValue(buf, 
> client.getVersion());
>     if ((b != null) && b.booleanValue()) {
>         eofIndicator = true;
>     }{code}
> Here, consider this situation, we're downloading file with 14B, remote server 
> adds EOF indicator to the end of the data, so it makes 15B, let's add some 
> necessary overhead (size etc.) which is, according to my experience, 13B, so 
> we receive 15 + 13 = 28B into initial buffer.
> Now, if we populate these variables, _dlen_ = 14B (file size), _rpos_ = 13 
> (overhead), and we set _buf.rpos_ to 27 (14 + 13), but _wpos_ is at the 
> moment equal to 28B, as that's what we received. (We're not taking EOF into 
> account here)
> Then the _SftpHelper.getEndOfFileIndicatorValue_ is called, which in it's 
> implementation looks like this:
> {code:java}
> public static Boolean getEndOfFileIndicatorValue(Buffer buffer, int version) {
>     return (version < SftpConstants.SFTP_V6) || (buffer.available() < 1) ? 
> null : buffer.getBoolean();
> }
> {code}
> Pay attention to the _buffer.available()_ function as it's implemented like 
> this:
> {code:java}
> public int available() {
>     return wpos - rpos;
> }
> {code}
> therefore returning 1 (28 - 27), condition is then resolved in 
> _SftpHelper.getEndOfFileIndicatorValue_ as a true and true is also returned 
> to the _pollBuffer_ and _eofIndicator_ is set to true.
> If you'd keep tracing further, you'd find out that the buffer is then never 
> read and returned from _SftpInputStreamAsync_ class, just because 
> _eofIndicator_ was set sooner than it should have been.
>  
>  



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@mina.apache.org
For additional commands, e-mail: dev-h...@mina.apache.org

Reply via email to