Compare commits

...
Author SHA1 Message Date
netcatty-bot 99a23c8f96 fix: address Codex review on PR #3202 2026-08-29 07:02:35 +00:00
2 changed files with 7 additions and 39 deletions

No files matched your search

+5 -13
View File
@@ -1517,19 +1517,11 @@ async function runRemoteUploadTransaction(client, localPath, remotePath, options
// back. Stop accepting cancellation before the final size verification so
// a late request cannot report the completed overwrite as cancelled.
commitPromotion();
// Some servers recreate the inode on OPEN|CREAT|TRUNC. Restore captured
// permission bits after an in-place overwrite (incl. stage→in-place
// fallback) so executable/setuid bits are not left at umask defaults.
// Do not forward the transfer AbortSignal: promotion already committed, and
// a late cancel must not abort required mode restoration (best-effort would
// otherwise swallow the failure and leave umask defaults).
if (Number.isFinite(plan.existingMode)) {
await restoreRemoteMode(client, encodedPath, plan.existingMode, {
bestEffort: false,
remotePath,
encoding,
});
}
// Some servers recreate the inode on OPEN|CREAT|TRUNC, so an in-place
// overwrite can leave the final path at umask defaults. Mode restoration is
// centralized post-commit in the upload-driver (transferBridge): it runs
// once, bounded and best-effort, so a stalled/failed chmod cannot report a
// successfully written upload as failed or duplicate a strict chmod here.
// SCP stat reports the link node itself. After an in-place symlink upload,
// it cannot reliably verify the followed target's byte count.
if (Number.isFinite(expectedSize) && expectedSize >= 0 && !(scpMode && plan.writeInPlace)) {
+2 -26
View File
@@ -2288,9 +2288,6 @@ async function uploadFile(
options = {},
) {
const generatedStagePath = options.generatedStagePath === true;
const existingRemoteMode = Number.isFinite(options.existingMode)
? options.existingMode & 0o7777
: null;
if (isScpModeClient(client)) {
transfer.pauseSupported = false;
transfer.pauseUnavailableReason = "Pause is unavailable for SCP transfers";
@@ -2347,17 +2344,6 @@ async function uploadFile(
});
}
await assertRemoteUploadSize(client, remotePath, fileSize);
// In-place replace writes the final path (fastPut / pipelined WRITE). Restore
// captured mode here; staged `.part` uploads restore after rename instead.
if (!generatedStagePath && Number.isFinite(existingRemoteMode)) {
await restoreRemoteUploadModeBestEffort(
client,
options.sftpId,
options.finalRemotePath || remotePath,
encoding,
existingRemoteMode,
);
}
};
// Prefer an isolated SFTP channel so cancellation cannot kill the browse session.
@@ -5943,12 +5929,7 @@ async function startTransferNow(event, payload, onProgress) {
sendProgress,
resolvedTargetEncoding,
usesStage ? null : () => { transfer.completionCommitted = true; },
{
generatedStagePath: usesStage,
existingMode: existingRemoteMode,
sftpId: targetSftpId,
finalRemotePath: targetPath,
},
{ generatedStagePath: usesStage },
);
},
});
@@ -6416,12 +6397,7 @@ async function startTransferNow(event, payload, onProgress) {
uploadProgress,
resolvedTargetEncoding,
usesStage ? null : () => { transfer.completionCommitted = true; },
{
generatedStagePath: usesStage,
existingMode: existingRemoteMode,
sftpId: targetSftpId,
finalRemotePath: targetPath,
},
{ generatedStagePath: usesStage },
);
},
});