Skip to content

fix(sftp): pass original position to read() callback instead of internal cursor#1489

Open
jeffrson wants to merge 2 commits intomscdex:masterfrom
jeffrson:master
Open

fix(sftp): pass original position to read() callback instead of internal cursor#1489
jeffrson wants to merge 2 commits intomscdex:masterfrom
jeffrson:master

Conversation

@jeffrson
Copy link
Copy Markdown

@jeffrson jeffrson commented Apr 3, 2026

Fixes #1488

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.

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