memory: fix dst mutating src after server-side copy

Before this change, the Memory backend's Copy method created a dst object that
referenced the src's objectData by pointer instead of making a copy. While this
minimized memory usage, an unintended consequence was that subsequently mutating
the src (such as changing the modtime) would inadvertently also mutate the dst,
and vice versa.

This change fixes the issue and adds a test.
This commit is contained in:
nielash 2024-03-25 10:20:01 -04:00
parent a67688dcc7
commit fecce67ac6
2 changed files with 9 additions and 1 deletions

View File

@ -482,7 +482,8 @@ func (f *Fs) Copy(ctx context.Context, src fs.Object, remote string) (fs.Object,
if od == nil {
return nil, fs.ErrorObjectNotFound
}
buckets.updateObjectData(dstBucket, dstPath, od)
odCopy := *od
buckets.updateObjectData(dstBucket, dstPath, &odCopy)
return f.NewObject(ctx, remote)
}

View File

@ -1237,6 +1237,13 @@ func Run(t *testing.T, opt *Opt) {
// Check dst lightly - list above has checked ModTime/Hashes
assert.Equal(t, file2Copy.Path, dst.Remote())
// check that mutating dst does not mutate src
err = dst.SetModTime(ctx, fstest.Time("2004-03-03T04:05:06.499999999Z"))
if err != fs.ErrorCantSetModTimeWithoutDelete && err != fs.ErrorCantSetModTime {
assert.NoError(t, err)
assert.False(t, src.ModTime(ctx).Equal(dst.ModTime(ctx)), "mutating dst should not mutate src -- is it Copying by pointer?")
}
// Delete copy
err = dst.Remove(ctx)
require.NoError(t, err)