From 88e516adee46f439cd0f53ccbbf3b7a86272e538 Mon Sep 17 00:00:00 2001 From: nielash Date: Tue, 10 Oct 2023 07:21:56 -0400 Subject: [PATCH] moveOrCopyFile: avoid panic on --dry-run Before this change, changing the case of a file on a case insensitive remote would fatally panic when `--dry-run` was set, due to `moveOrCopyFile` attempting to access the non-existent `tmpObj` it (would normally have) created. After this change, the panic is avoided by skipping this step during a `--dry-run` (with the usual "skipped as --dry-run is set" log message.) --- fs/operations/operations.go | 4 ++++ fs/operations/operations_test.go | 17 +++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/fs/operations/operations.go b/fs/operations/operations.go index efa3d4bab..b71e6adc5 100644 --- a/fs/operations/operations.go +++ b/fs/operations/operations.go @@ -1770,6 +1770,10 @@ func moveOrCopyFile(ctx context.Context, fdst fs.Fs, fsrc fs.Fs, dstFileName str // move it back to the intended destination. This is required // to avoid issues with certain remotes and avoid file deletion. if !cp && fdst.Name() == fsrc.Name() && fdst.Features().CaseInsensitive && dstFileName != srcFileName && strings.EqualFold(dstFilePath, srcFilePath) { + if SkipDestructive(ctx, srcFileName, "rename to "+dstFileName) { + // avoid fatalpanic on --dry-run (trying to access non-existent tmpObj) + return nil + } // Create random name to temporarily move file to tmpObjName := dstFileName + "-rclone-move-" + random.String(8) tmpObjFail, err := fdst.NewObject(ctx, tmpObjName) diff --git a/fs/operations/operations_test.go b/fs/operations/operations_test.go index 19d58ea30..325db1748 100644 --- a/fs/operations/operations_test.go +++ b/fs/operations/operations_test.go @@ -997,6 +997,23 @@ func TestCaseInsensitiveMoveFile(t *testing.T) { r.CheckRemoteItems(t, file2Capitalized) } +func TestCaseInsensitiveMoveFileDryRun(t *testing.T) { + ctx := context.Background() + ctx, ci := fs.AddConfig(ctx) + r := fstest.NewRun(t) + if !r.Fremote.Features().CaseInsensitive { + return + } + + ci.DryRun = true + file1 := r.WriteObject(ctx, "hello", "world", t1) + r.CheckRemoteItems(t, file1) + + err := operations.MoveFile(ctx, r.Fremote, r.Fremote, "HELLO", file1.Path) + require.NoError(t, err) + r.CheckRemoteItems(t, file1) +} + func TestMoveFileBackupDir(t *testing.T) { ctx := context.Background() ctx, ci := fs.AddConfig(ctx)