Skip to content

scp: fix duplicate file header on send#1128

Open
ejohnstown wants to merge 1 commit into
wolfSSL:masterfrom
ejohnstown:fix-scp-dupe-header
Open

scp: fix duplicate file header on send#1128
ejohnstown wants to merge 1 commit into
wolfSSL:masterfrom
ejohnstown:fix-scp-dupe-header

Conversation

@ejohnstown

Copy link
Copy Markdown
Contributor
  • Gate header on new scpFileHeaderSent flag, not scpFileOffset==0
  • A send callback returning 0 bytes first no longer re-sends header
  • Skip zero-length SCP_SEND_FILE send to avoid empty CHANNEL_DATA
  • Reset offset/bufferedSz/flag in ScpSourceInit for connection reuse
  • Add test_wolfSSH_SCP_SendZeroFirst regression (func_args scp_send hook)

Issue: ZD-22176

Copilot AI review requested due to automatic review settings July 23, 2026 22:36

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Fixes an SCP server-side edge case where the file header could be transmitted more than once when the SCP send callback returns 0 bytes on its first invocation, and adds a regression test by allowing tests to inject a custom SCP send callback into the echoserver harness.

Changes:

  • Add scpFileHeaderSent state to gate header emission per file (instead of relying on scpFileOffset == 0).
  • Avoid emitting zero-length CHANNEL_DATA when the send buffer is empty, and reset SCP per-file state on source init / connection reuse paths.
  • Add test_wolfSSH_SCP_SendZeroFirst regression test and enable callback injection via func_args.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
wolfssh/test.h Includes wolfscp.h under WOLFSSH_SCP and extends func_args with an injectable scp_send callback.
wolfssh/internal.h Adds scpFileHeaderSent to SCP state tracked on the WOLFSSH object.
tests/api.c Adds a regression test ensuring a 0-byte-first send callback does not cause a duplicated SCP file header.
src/wolfscp.c Uses scpFileHeaderSent to gate header sending, skips zero-length sends, and resets per-file state for reuse.
src/internal.c Initializes scpFileHeaderSent during SSH session initialization.
examples/echoserver/echoserver.c Applies an injected SCP send callback to the server context for tests.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/wolfscp.c
Comment on lines 375 to +389
/* file buffer */
ssh->scpFileBuffer = (byte*)WMALLOC(DEFAULT_SCP_BUFFER_SZ, ssh->ctx->heap,
DYNTYPE_BUFFER);
if (ssh->scpFileBuffer == NULL) {
WFREE(ssh->scpFileName, ssh->ctx->heap, DYNTYPE_STRING);
ssh->scpFileName = NULL;
return WS_MEMORY_E;
}
ssh->scpFileBufferSz = DEFAULT_SCP_BUFFER_SZ;
WMEMSET(ssh->scpFileBuffer, 0, DEFAULT_SCP_BUFFER_SZ);

/* reset per-file state so a reused connection starts a fresh transfer */
ssh->scpFileOffset = 0;
ssh->scpBufferedSz = 0;
ssh->scpFileHeaderSent = 0;
- Gate header on new scpFileHeaderSent flag, not scpFileOffset==0
- A send callback returning 0 bytes first no longer re-sends header
- Skip zero-length SCP_SEND_FILE send to avoid empty CHANNEL_DATA
- Reset offset/bufferedSz/flag in ScpSourceInit for connection reuse
- Add test_wolfSSH_SCP_SendZeroFirst regression (func_args scp_send hook)
- Zero func_args in kex.c/testsuite.c so the new scp_send field is not read uninitialized

Issue: ZD-22176
@ejohnstown
ejohnstown force-pushed the fix-scp-dupe-header branch from e0d32bb to ec84812 Compare July 23, 2026 22:54
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.

2 participants