Skip to content

fix(sftp): pass original position to read() callback instead of internal cursorRead overflow cb position#1503

Open
jeffrson wants to merge 2 commits into
mscdex:masterfrom
jeffrson:read-overflow-cb-position
Open

fix(sftp): pass original position to read() callback instead of internal cursorRead overflow cb position#1503
jeffrson wants to merge 2 commits into
mscdex:masterfrom
jeffrson:read-overflow-cb-position

Conversation

@jeffrson

Copy link
Copy Markdown

Fixes #1488
(I'm sorry - this is the same as #1489, but I had to change branches and so it was closed automatically by Github)

Problem

sftp.read(handle, buf, off, len, position, cb) passes the wrong value as the position argument to cb when len exceeds _maxReadLen. The internal field req.position is used both as a mutable cursor for sequential sub-reads and as the return value for the user callback — so the callback always receives the end-offset of the last sub-read instead of the original position.

Fix

Introduce req.origPosition to preserve the original value across sub-reads, analogous to the existing req.origOff pattern for the off argument.

Diff

 const req = (req_ || {
   nb: 0,
   position,
  • origPosition: position,
    off,
    origOff: off,
    ...
    cb: (err, data, nb) => {
    ...
  •  cb(undefined, req.nb + nb, data, req.position);
    
  •  cb(undefined, req.nb + nb, data, req.origPosition);
    
    },
    });
    Testing

Triggers reliably with any non-OpenSSH server and a read request > 31952 bytes
With OpenSSH servers the same bug occurs for requests > 260096 bytes (~254 KB)
Prior art

This was previously reported as part of #1171 (attached to a different bug). The PR also contains a test case demonstrating the failure.
And of course, as mentioned previously, it is the same as #1489

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

sftp.read callback receives wrong position value when request exceeds _maxReadLen

1 participant