diff --git a/fs/accounting/accounting.go b/fs/accounting/accounting.go index 587683e49..36602568a 100644 --- a/fs/accounting/accounting.go +++ b/fs/accounting/accounting.go @@ -521,9 +521,17 @@ type accountWriteTo struct { func (awt *accountWriteTo) Write(p []byte) (n int, err error) { bytesUntilLimit, err := awt.acc.checkReadBefore() if err == nil { + // Truncate the write to the transfer limit + truncated := int64(len(p)) > bytesUntilLimit + if truncated { + p = p[:bytesUntilLimit] + } n, err = awt.w.Write(p) n, err = awt.acc.checkReadAfter(bytesUntilLimit, n, err) awt.acc.accountRead(n) + if truncated && err == nil { + err = ErrorMaxTransferLimitReachedFatal + } } return n, err } diff --git a/fs/accounting/accounting_test.go b/fs/accounting/accounting_test.go index c8c933d37..af01b0f79 100644 --- a/fs/accounting/accounting_test.go +++ b/fs/accounting/accounting_test.go @@ -321,6 +321,8 @@ func TestAccountMaxTransferWriteTo(t *testing.T) { n, err := acc.WriteTo(&b) assert.Equal(t, int64(15), n) assert.Equal(t, ErrorMaxTransferLimitReachedFatal, err) + // Nothing past the limit must reach the writer + assert.Equal(t, 15, b.Len()) } func TestAccountReadCtx(t *testing.T) {