Commit Graph
100 Commits
Author SHA1 Message Date
Nick Craig-Wood 1fd40d06ab Add no-hup to contributors 2026-08-27 17:28:04 +01:00
Nick Craig-Wood 02a6f8bae6 Add shaurya to contributors 2026-08-27 17:28:04 +01:00
Nick Craig-Wood aa2b879c67 Add cyphercodes to contributors 2026-08-27 17:28:04 +01:00
Nick Craig-Wood 0c4f61b972 Add Anatoly Tarnavsky to contributors 2026-08-27 17:28:04 +01:00
Nick Craig-Wood 8494fc7498 Add Sune Mølgaard to contributors 2026-08-27 17:28:04 +01:00
Nick Craig-Wood a00f9bf4e1 Add Vijay Misal to contributors 2026-08-27 17:28:04 +01:00
Nick Craig-Wood 5d2fe5e52f Add Rayan Salhab to contributors 2026-08-27 17:28:04 +01:00
Nick Craig-Wood a93a062f4a Add water to contributors 2026-08-27 17:28:04 +01:00
Nick Craig-Wood 7897f1d30f Add shaurya to contributors 2026-08-27 17:28:04 +01:00
Nick Craig-Wood e3aeaee13d Add CAOShurong to contributors 2026-08-27 17:28:03 +01:00
Nick Craig-Wood c140d36a1f docs: update sponsors 2026-08-26 12:09:58 +01:00
Nick Craig-Wood 4369d16a1c test_all: pikpak: ignore TestRcatSizeChecksum/Corrupted
Pikpak never returns MD5 for uploads which causes this test to fail.

Perhaps Pikpak should not declare MD5 but that is a bigger decision
being discussed in #9826
2026-08-26 12:00:22 +01:00
Nick Craig-Wood f7c510af49 webdav: fix SetModTime failing and hashes missing on Nextcloud
Nextcloud only stores a checksum which is supplied in the OC-Checksum
header of an upload, and discards it again when the modification time
is set with PROPPATCH. Re-sending the checksum in the PROPPATCH (as is
done for ownCloud) is rejected by Nextcloud with 403 Forbidden which
made the whole PROPPATCH fail, so SetModTime returned an error on any
object which had a hash. Uploads from sources without hashes, eg
streamed uploads with `rclone rcat`, were stored with no hash at all.

Use the Nextcloud PATCH extension with the X-Recalculate-Hash header
to have the server calculate and store the SHA1 of an object after a
streamed upload and after setting the modification time. This gives
a server side hash of the stored data which also lets rclone verify
streamed uploads.
2026-08-26 12:00:22 +01:00
Nick Craig-Wood 8e744de5e6 pikpak: fix truncated single part uploads reported as ok when source ends early
If the source supplied fewer bytes than its declared size, the single
part upload path accepted the short body and stored a truncated file
recorded with the declared size, reporting a successful upload. The
multipart path already checks for this.

Count the bytes actually read and fail the upload if they do not match
the declared size, which cancels the partially created file.

This was found by the FsPutShortEOF integration test.
2026-08-26 12:00:22 +01:00
Nick Craig-Wood a893df601a Add machsix to contributors 2026-08-26 12:00:22 +01:00
Nick Craig-Wood d3a71eea36 azureblob: fix test which didn't compile
We accidentally merged this commit with non compiling tests.

bee45bccfd azureblob: fix spurious vfs cache corruption errors during chunked reads #9782
2026-08-25 09:31:40 +01:00
Nick Craig-Wood d68ecd1717 Add Sanjay Kanth A to contributors 2026-08-25 09:31:40 +01:00
Nick Craig-Wood bee45bccfd azureblob: fix spurious vfs cache corruption errors during chunked reads - fixes #9782
On a ranged download the metadata decoder stored the response's
Content-Length (the length of the range, not the blob) in the object's
size and only corrected it from the Content-Range total afterwards.
Object.Size() is read concurrently by the VFS cache and chunked reader
while a download is in progress, so with --vfs-read-chunk-size a reader
could observe the chunk length (e.g. 67108864 for 64M chunks) as the
object size. The VFS cache then logged

    vfs cache: cached file (N) is unexpectedly larger than the remote
    object (67108864). The cached file is likely corrupted after an
    unclean shutdown; recovering ...

and truncated the read request against the bogus size, breaking
sequential reads of large blobs with --vfs-cache-mode full.

This applies the Content-Range correction before the size is stored so
the range length is never published as the object size.
2026-08-24 18:16:12 +01:00
Nick Craig-Wood 2a8d8afd0f lib/rest: make ParseContentRange public 2026-08-24 18:16:12 +01:00
Nick Craig-Wood d9aa903358 protondrive: fix files uploaded with v1.75.0 not being readable in the Proton apps
rclone v1.75.0 started creating files in Proton Drive's new
crypto-refresh encryption format, following guidance from Proton that
new file node keys should use the v6/AEAD profile. It turns out the
official Proton web app cannot decrypt files whose node key is a v6
key (but the Android app can), so every file uploaded with v1.75.0 (or
a beta after 2026-07-13) shows 'Item cannot be decrypted' in the web
app, even though rclone itself reads the files fine. Inspecting a file
created by the web app shows Proton itself still creates v4 node keys,
using the new format only for the file content.

New files are now created with the same fully pre-crypto-refresh
format as v1.74.4 (v4 node key, v3 PKESK content key, v1 SEIPD
blocks), which every Proton client can read. Reading files in the new
format still works, new revisions of files which already use the new
content format keep it, and the auxiliary fields (name, node
passphrase, extended attributes, block signatures) are pinned to the
old format regardless of the recipient key's preferences, as Proton
requires.

Files already uploaded with v1.75.0 cannot be repaired in place -
uploading a new revision does not change the file's node key. To make
such a file readable by the Proton apps again, delete it from the
remote and upload it again with a fixed version of rclone.

This updates Proton-API-Bridge to v1.0.5 and go-proton-api to v1.0.4.

See: https://forum.rclone.org/t/proton-drive-unable-to-decrypt/54087
2026-08-24 17:47:13 +01:00
Nick Craig-Wood c7be826d7b Add Rahman Yilmaz to contributors 2026-08-24 17:47:13 +01:00
Nick Craig-Wood 3c1a265842 Add Rohit Behera to contributors 2026-08-24 17:47:13 +01:00
Nick Craig-Wood be7f9b38b0 build: untap aws/tap to silence homebrew tap trust warnings on macOS 2026-08-21 12:52:12 +01:00
Nick Craig-Wood 0027678977 huaweidrive: simplify chunk size clamping found by "go fix -minmax" 2026-08-21 12:23:31 +01:00
Nick Craig-Wood a017a54bef build: modernize with "go fix -waitgroupgo": use WaitGroup.Go 2026-08-21 12:23:31 +01:00
Nick Craig-Wood 2d1a3386a8 build: modernize with "go fix -stringsseq": use SplitSeq iterators 2026-08-21 12:23:31 +01:00
Nick Craig-Wood aed06f9052 build: modernize with "go fix -stringscutprefix": use strings.CutPrefix 2026-08-21 12:23:31 +01:00
Nick Craig-Wood 7b002153bd build: modernize with "go fix -stringscut": use strings.Cut 2026-08-21 12:23:31 +01:00
Nick Craig-Wood 4e9577ed76 build: modernize with "go fix -stringsbuilder": use strings.Builder 2026-08-21 12:23:31 +01:00
Nick Craig-Wood 9f9fd82923 build: modernize with "go fix -slicescontains": use slices.Contains 2026-08-21 12:23:31 +01:00
Nick Craig-Wood 237719bb8d build: modernize with "go fix -slicesbackward": use slices.Backward 2026-08-21 12:23:31 +01:00
Nick Craig-Wood e20e18d2e0 build: modernize with "go fix -reflecttypefor": use reflect.TypeFor 2026-08-21 12:23:31 +01:00
Nick Craig-Wood a64c0a0fde build: modernize with "go fix -rangeint": use range over int 2026-08-21 12:23:31 +01:00
Nick Craig-Wood 67728ce37d huaweidrive: remove no-op omitempty found by "go fix -omitzero" 2026-08-21 12:23:31 +01:00
Nick Craig-Wood 53d9f7f956 build: modernize with "go fix -newexpr": use go1.26 new(expr)
Also inline and remove the now unneeded pointer helper functions.
2026-08-21 12:23:31 +01:00
Nick Craig-Wood b5bea683c5 build: modernize with "go fix -minmax": use min and max builtins 2026-08-21 12:23:31 +01:00
Nick Craig-Wood bfd0e3f3c2 build: modernize with "go fix -mapsloop": use maps.Copy 2026-08-21 12:23:31 +01:00
Nick Craig-Wood 33e9251b52 build: modernize with "go fix -errorsastype": use errors.AsType 2026-08-21 12:23:31 +01:00
Nick Craig-Wood 77f9c70cf6 build: modernize with "go fix -atomictypes": use sync/atomic types 2026-08-21 12:23:31 +01:00
Nick Craig-Wood 7929921ed8 build: modernize with "go fix -any": replace interface{} with any 2026-08-21 12:23:31 +01:00
Nick Craig-Wood 357c2a2b44 build: disable staticcheck SA4023 to fix lint job timeout
The dataflow analysis behind SA4023, new in the staticcheck 0.8.0
bundled with golangci-lint v2.13.0, makes linting large packages more
than 10x slower (89s vs 7s for backend/s3 alone) which took the CI
lint job past its 30 minute limit. golangci-lint no longer enforces
its run timeout during analysis so the job ran until cancelled, and
the cancellation meant the lint cache was never saved, making every
subsequent run cold and guaranteeing the timeout repeated.

The check also produces false positives (eg claiming operations.Delete
never returns nil).
2026-08-21 12:23:31 +01:00
Nick Craig-Wood 152adfcd2a serve s3: update to gofakes3 v0.0.8 which fixes 500 errors with go1.27 2026-08-21 12:23:31 +01:00
Nick Craig-Wood e189f38122 build: update to go1.27 and make go1.26 the minimum required version 2026-08-20 12:16:48 +01:00
Nick Craig-Wood ec3a95c279 s3: Mega: update endpoints 2026-08-20 12:12:00 +01:00
Nick Craig-Wood 2f7d4e3f9f rc: deprecate --rc-web-gui flag
This commit removes the workings of the old web ui which hasn't been
maintained for 6 years. If users supply --rc-web-gui then rclone will
exit with an error pointing users at the maintained `rclone gui`
command.
2026-08-19 12:15:00 +01:00
Nick Craig-Wood 00496f5dfb docs: take gui out of beta 2026-08-18 14:29:43 +01:00
Nick Craig-Wood 2c1174af0d docs: add assigned CVE numbers to the v1.75.0 security advisories in the changelog
Five of the advisories released with v1.75.0 now have CVEs assigned:

- GHSA-45pq-889g-fcgh serve restic path traversal: CVE-2026-71309
- GHSA-xhf4-832v-7xcr lib/proxy CONNECT header OOM: CVE-2026-71310
- GHSA-8c48-q9wj-3w37 ftp command injection: CVE-2026-71311
- GHSA-2m8m-jhrm-w6j2 sftp PowerShell command injection: CVE-2026-71312
- GHSA-7p4m-qxvv-g567 local file name escape: CVE-2026-71313

GHSA-6jcg-q3wp-x2f4 (squashfs) loses its CVE-PENDING marker as GitHub
declined to issue a CVE from the rclone repository - the vulnerable code
is in go-diskfs so any CVE must come from an advisory there.

GHSA-mfvx-7rcj-9m5g (pprof) keeps its CVE-PENDING marker as the CVE
request is still awaiting allocation.
2026-08-18 12:29:35 +01:00
Nick Craig-Wood b13f62237a Add VXNCXNX to contributors 2026-08-18 12:29:35 +01:00
Nick Craig-Wood 8da69d8775 Add Shantanav Mukherjee to contributors 2026-08-18 12:29:35 +01:00
Nick Craig-Wood 5b417ce5a1 Add Hakan İSMAİL to contributors 2026-08-18 12:29:35 +01:00
Nick Craig-Wood 47b1ac9540 Add max to contributors 2026-08-18 12:29:35 +01:00
Nick Craig-Wood f0b210a886 build: fix multiple CVEs by upgrading to go1.26.6
- CVE-2026-56860: net/url: quadratic complexity in resolvePath
- CVE-2026-56858: html/template: JavaScript regexp context tracking
- CVE-2026-56862: crypto/tls: limit handshake messages accepted post-handshake
- CVE-2026-56853: net/http: apply ReadHeaderTimeout to unencrypted HTTP/2 check
- CVE-2026-56859: encoding/xml: recursion depth guard during decode
- CVE-2026-33818: encoding/asn1: enforce maximum recursion depth
- CVE-2026-46600: net: panic parsing an invalid SVCB or HTTPS RR in dnsmessage
- CVE-2026-39821: net/http: reject ASCII-only Punycode-encoded labels in idna

This also updates the go1.25 test job to go1.25.13 which contains the
same fixes.
2026-08-14 19:18:26 +01:00
Nick Craig-Wood 00593a96fe build: update golang.org/x/image to v0.45.0 to fix CVE-2026-46603
CVE-2026-46603: excessive memory allocation during VP8L decoding

This also updates golang.org/x/text to v0.41.0 as a dependency.
2026-08-14 19:18:26 +01:00
Nick Craig-Wood 64c9a28651 Add Dave to contributors 2026-08-14 19:18:26 +01:00
Nick Craig-Wood f81ccdf786 Add Shurong Cao to contributors 2026-08-14 19:18:26 +01:00
Nick Craig-Wood 8aba1c4378 Add Morax to contributors 2026-08-14 19:18:26 +01:00
Nick Craig-Wood 5a0b7d6746 crypt: fix hash mismatches with no_data_encryption on backends which check upload hashes
Before this change, when no_data_encryption was set, uploads from
local disk advertised the hash of the encrypted data even though the
data was uploaded unencrypted.

On backends which check upload hashes (eg b2) this made uploads of
small files fail with errors like "Checksum did not match data
received", and made chunked uploads store an incorrect hash so the
files failed their checksum on download with "corrupted on transfer:
SHA1 hashes differ".

See: https://forum.rclone.org/t/sha1-mismatches-on-b2-with-no-data-encryption-true/54121
2026-08-14 09:54:00 +01:00
Nick Craig-Wood afb4fa5f2b Add Pastalikek65 to contributors 2026-08-14 09:54:00 +01:00
Nick Craig-Wood d22c4509aa Add Dean Chen to contributors 2026-08-14 09:54:00 +01:00
Nick Craig-Wood f49e051507 Add Teddy Tennant to contributors 2026-08-14 09:54:00 +01:00
Nick Craig-Wood 926ccdac5d Add Jiacheng Xu to contributors 2026-08-14 09:54:00 +01:00
Nick Craig-Wood 49dc9fb919 Add Recoordinate to contributors 2026-08-14 09:54:00 +01:00
Nick Craig-Wood 7c7635bae3 Add Rodrigo Rodrigues to contributors 2026-08-14 09:54:00 +01:00
Nick Craig-Wood 86f981a05e Add Christian De Santis to contributors 2026-08-14 09:54:00 +01:00
Nick Craig-Wood 1947e4217c serve s3: clean up abandoned multipart uploads after --multipart-expiry
A client which started a multipart upload and vanished without either
completing or aborting it used to hold on to its resources forever.

Incomplete multipart uploads which have had no activity for
--multipart-expiry (default 24h) are now aborted and cleaned up
exactly as if the client had called AbortMultipartUpload, with a
NOTICE logged.

An upload with a part still being received is never expired, and each
completed part restarts the clock. Late operations on an expired
upload fail with NoSuchUpload, as they do on real S3 when a lifecycle
rule has aborted the upload.

Set --multipart-expiry 0 to keep incomplete uploads forever.
2026-08-11 20:58:48 +01:00
Nick Craig-Wood b4db289d0a serve s3: upload all multipart uploads via the VFS
Multipart uploads used to be streamed directly to the remote with their
own PutStream machinery, bypassing the VFS, a design left over from
before the VFS could abandon a streaming write.

They are now written through the VFS exactly like plain object PUTs in
every cache mode. The parts are written, in part-number order, to a
temporary object which is renamed into place server-side on
completion.

With the default --vfs-cache-mode off the parts stream through the VFS
to the remote as they arrive. With --vfs-cache-mode writes or above
they are buffered in the VFS cache and uploaded by its write-back.

User visible changes:

- Multipart uploads now show in rclone's transfer stats and obey
  --bwlimit (previously they bypassed both).
- Remotes without streaming upload support now spool the upload to a
  temporary file on local disk instead of buffering it in memory.
- Multipart uploads are never buffered in memory because of missing
  remote capabilities - only --disable-multipart-streaming does that.
- Remotes that upload atomically now also write to a temporary object
  renamed into place, so an in-progress multipart upload is no longer
  briefly visible under its final key.
- On the few remotes with no server-side move or copy the parts are
  written straight to the final object in all cache modes.
- With --vfs-cache-mode writes, plain PUTs and multipart uploads to the
  same key go through the same cache entry, so an earlier PUT still in
  the write-back window can no longer be written back over a newer
  multipart upload.
- Failed write-backs are retried by the VFS without the client having
  to restart the upload, and completed objects are served from the
  cache for read-after-write.
2026-08-11 20:58:48 +01:00
Nick Craig-Wood 0aa90200bd serve s3: reserve the .rclone_temp_ prefix for temporary objects
The temporary objects that uploads are written to before being renamed
into place are now named .rclone_temp_put_* and .rclone_temp_multipart_*,
and the whole .rclone_temp_ prefix is reserved: any object whose name
starts with it is hidden from S3 listings. This gives a single pattern
for cleaning up leftovers from killed servers:

    rclone delete --min-age 24h --include ".rclone_temp_*" remote:path

The .rclone_multipart_upload_* objects rclone v1.75 used are still
hidden from listings so leftovers from an older server stay invisible
to S3 clients.
2026-08-11 20:58:48 +01:00
Nick Craig-Wood a3489456de serve s3: fix modtime not being set when only mtime metadata is supplied on PUT
The mtime metadata fallback was nested inside the X-Amz-Meta-Mtime
branch, so it only ran when X-Amz-Meta-Mtime was present but invalid -
and then set the modtime from the invalid value's failed parse rather
than parsing mtime. An object PUT with only mtime metadata kept the
upload time as its modtime.

Now the two keys are checked independently, as TouchObject already
does.
2026-08-11 20:58:48 +01:00
Nick Craig-Wood 531d873bd7 serve s3: fix crash when a multipart upload is aborted while a part is uploading
streamPart did not check whether the upload had been torn down, but
AbortMultipartUpload sets the reorder buffer map to nil, so an abort
arriving while a part body was still being received panicked with an
assignment to a nil map once the part was buffered.

Now a part whose upload has been aborted or completed under it is
rejected with NoSuchUpload.
2026-08-11 20:58:48 +01:00
Nick Craig-Wood 84298fc090 serve s3: fix failed uploads deleting or corrupting the object at the key - fixes #9718
A PUT which failed part way through removed the object at the
destination key. As well as differing from real S3 (where a failed PUT
never affects the stored object), this raced with the client's
automatic retry of the same PUT: the retry stored the object and
returned 200 OK, then the failed first attempt's cleanup deleted it,
silently losing an acknowledged upload. The interrupted upload could
also be committed as a truncated object, since closing the write handle
gave the streaming upload a clean end of stream.

Now a failed or interrupted PUT never disturbs the object at the key:

- The object at the key is never removed on error.
- On backends where a partial upload is visible at its final name
  (PartialUploads), and when the VFS cache mode is writes or above, the
  upload is written to a temporary object which is renamed into place
  on success and removed on failure, as streamed multipart uploads
  already do. Backends which upload atomically are still streamed
  straight to the destination.
- An interrupted or short body fails the upload via
  WriteFileHandle.CloseWithError instead of committing truncated data,
  and a body which ends cleanly short of its declared size is rejected
  with IncompleteBody.
2026-08-11 20:58:48 +01:00
Nick Craig-Wood 2f0657c35b vfs: add WriteFileHandle.CloseWithError to abandon streaming writes
Closing a streaming write handle sends a clean EOF to the backend
upload, so a writer which knows its data source failed part way through
had no way to stop the truncated file being stored as if it were
complete.

CloseWithError closes the handle failing the upload with the given
reason instead. EOF-like reasons are rewritten so the layers reading
the pipe can't mistake them for a clean end of stream and commit the
partial file.

Needed by serve s3 to abort interrupted PUTs - see #9718
2026-08-11 20:58:48 +01:00
Nick Craig-Wood 7357fb82a9 internetarchive: fix corrupted files being created when the source ends early
If the source supplied fewer bytes than its declared size, the upload
request failed but a retry could report success even though the stored
file was truncated, because the retry re-sent an already exhausted
reader.

Count the bytes actually read from the source and if they do not match
the declared size return an error.

This was found by the new FsPutShortEOF integration test.
2026-08-11 19:32:12 +01:00
Nick Craig-Wood 5d057549b9 sia: fix corrupted files being created when the source ends early
If the source supplied fewer bytes than its declared size, the upload
request failed but a retry could report success even though the stored
file was truncated, because the retry re-sent an already exhausted
reader.

Count the bytes actually read from the source and if they do not match
the declared size, remove the partially uploaded file and return an
error.

This was found by the new FsPutShortEOF integration test.
2026-08-11 19:32:12 +01:00
Nick Craig-Wood a2baa978db pikpak: fix truncated files being created when the source ends early
If the source supplied fewer bytes than its declared size, the
multipart upload was completed anyway, storing a truncated file and
reporting a successful upload.

Check the number of bytes read from the source against the declared
size before finalising and abort the upload with an error if they do
not match.

This was found by the new FsPutShortEOF integration test.
2026-08-11 19:32:12 +01:00
Nick Craig-Wood 5b7cc097e3 multipart: fix chunked uploads storing truncated objects when the source ends early
If the source supplied fewer bytes than its declared size, the
multipart upload was completed anyway, storing a truncated object and
reporting a successful upload.

Check the number of bytes read from the source against the declared
size before finalising and abort the upload with an error if they do
not match.

This affects all backends which use lib/multipart for chunked uploads:
azureblob, b2, drime, internxt, oracleobjectstorage, s3 and shade.

This was found by the new FsPutShortEOF and TestRcatSizeShortEOF
integration tests.
2026-08-11 19:32:12 +01:00
Nick Craig-Wood e1bf9405e2 filelu: fix truncated files being uploaded successfully when the source ends early
If the source supplied fewer bytes than its declared size, the
truncated file was stored and the upload reported success with the
object claiming the declared size.

Count the bytes actually read from the source and if they do not match
the declared size, remove the truncated file and return an error.

This was found by the new TestRcatSizeShortEOF integration test.
2026-08-11 19:32:12 +01:00
Nick Craig-Wood 884b28c203 azurefiles: fix zero padded files being created when the source ends early
The file is created at the declared size and the data then written
with ranged writes, so if the source supplied fewer bytes than
declared, the remainder of the file was left as zeroes and the upload
reported success.

Count the bytes actually read from the source and if they do not match
the declared size, delete the partially uploaded file (if newly
created) and return an error.

This was found by the new FsPutShortEOF and TestRcatSizeShortEOF
integration tests.
2026-08-11 19:32:12 +01:00
Nick Craig-Wood 1aa9efef17 docs: update sponsor links 2026-08-07 16:28:43 +01:00
Nick Craig-Wood 345758454c Add Edward Klesel to contributors 2026-08-07 16:28:43 +01:00
Nick Craig-Wood 5629f2668c overview: fix "internal error: no overview data found" on 32 bit architectures - fixes #9723
The precision field in the backend overview YAML files can hold
fs.ModTimeNotSupported (100 years in nanoseconds) which overflows int
on 32 bit platforms, making the YAML for those backends fail to parse
and causing rclone to log 18 internal errors on every invocation.

Use int64 for the precision field and add a test that parses every
embedded backend YAML file so this is caught on 32 bit test runs.
2026-08-04 19:29:21 +01:00
Nick Craig-Wood a06df7a2de protondrive: fix corrupted uploads after a retried upload error - fixes #9722
When an upload failed part way through with a retryable error (eg a
502 from the block storage servers) the pacer retried the whole upload
call with the same input stream. The stream had already been partially
consumed, so the retry re-created the upload draft and committed just
the remainder of the stream as a complete file, silently truncating
it. With restic over serve restic this corrupted the repository as the
truncated pack was reported as successfully uploaded.

This fixes it by using CallNoRetry for the upload, as the other
backends do, so retryable errors are returned wrapped in a RetryError
for the caller to retry the upload with a fresh stream.
2026-08-04 19:29:21 +01:00
Nick Craig-Wood 9b13247ba8 operations: fix silent truncation of streaming uploads whose source ends early
Uploads through RcatSize with a known size - used by rcat --size, the
rc operations/uploadfile and the serve backends, eg serve restic - did
not check the size of the uploaded object. If the source stream ended
before the declared size worth of data had been read, the truncated
object was reported as a successful upload. This could corrupt data
for callers which trust the result, eg a restic repository accessed
via serve restic (see #9722).

This adds the same size check operations.Copy performs after a copy,
respecting --ignore-size and backends which do not report sizes.
2026-08-04 19:29:21 +01:00
Nick Craig-Wood 1318962a96 docs: fix width of sponsor images on very big screens 2026-08-04 19:29:21 +01:00
Nick Craig-Wood 52b5c4d6c2 Add Anton Karpov to contributors 2026-08-04 19:29:21 +01:00
Nick Craig-Wood 18fa445ffc compress: fix corrupted objects being created when the source ends early
When the source supplied fewer bytes than its declared size, the
compressed data file was stored under a name containing the declared
size while the metadata recorded the actual number of bytes read.
NewObject looks the data file up by the size in the metadata, so the
resulting object could never be read again, and the upload reported
success.

Check that the number of bytes read matches the declared size after
uploading the data and before writing the metadata, and remove the
data file and return an error if it does not.

This was found by the new FsPutShortEOF integration test.
2026-08-03 20:58:14 +01:00
Nick Craig-Wood e0701daea0 dropbox: don't retry chunked upload requests when the upload has been cancelled
The append loop retries everything once the upload session has
started, so a cancelled context error was retried through all the low
level retries with exponential backoff before the upload gave up.
2026-08-03 20:58:14 +01:00
Nick Craig-Wood bff17664ad dropbox: fix chunked uploads of truncated files never finishing - fixes #9704
A source which returned EOF before supplying as many bytes as it
declared would either commit a truncated file (if the shortfall was
within the final chunk) or loop forever appending empty chunks to the
upload session. Return an error wrapping io.ErrUnexpectedEOF instead.

Note that all dropbox uploads use the chunked upload path with the
default batch_mode of sync, so this affected uploads of every size.
2026-08-03 20:58:14 +01:00
Nick Craig-Wood 03f8582a55 fstests: check uploads terminate when the source ends before its declared size
A source reader which returns EOF before supplying as many bytes as it
declared should not cause a backend Put to hang, panic or create an
object claiming the declared size.

The layers above detect a truncated transfer by comparing sizes after
the upload, so a backend may either return an error or create a
shorter object.

See #9704
2026-08-03 20:58:14 +01:00
Nick Craig-Wood 5024425ba8 Add alliasgher to contributors 2026-08-03 20:58:14 +01:00
Nick Craig-Wood 3f9d583cff gitannex: reduce subprocess launches in end to end test setup
Write the git configuration for each test's fake home directory as a
file instead of running three "git config --global" commands, and drop
the "git annex version" invocation from repository setup. This removes
four subprocess launches from each of the fifteen test cases.
2026-08-02 18:25:09 +01:00
Nick Craig-Wood b6a82ee56c gitannex: run the end to end test functions in parallel
The subtests within each end to end test function already run in
parallel, but the three test functions themselves ran one after
another.

Marking the functions parallel lets all their subtests overlap.
2026-08-02 18:25:09 +01:00
Nick Craig-Wood c9cd065458 gitannex: skip end to end tests under the race detector
The end to end tests exercise rclone via a separate subprocess spawned
by git-annex, and that subprocess is not built with race
instrumentation.

Running them in the race test therefore adds several minutes to CI
without providing any race coverage. The unit tests in this package
still run under the race detector.
2026-08-02 18:25:09 +01:00
Nick Craig-Wood b3168b3ad6 gitannex: speed up the end to end tests with testremote --fast
Run the full "git annex testremote" suite for a single layout mode and
use "testremote --fast" for the rest.

The full suite repeats the same protocol operations across a matrix of
key sizes and chunk configurations, which exercises client side
git-annex behaviour rather than rclone.
2026-08-02 18:25:09 +01:00
Nick Craig-Wood c4e82700cb gitannex: speed up the end to end tests by removing redundant checks
The migration test ran the full "git annex testremote" suite for every
layout mode after verifying the migration with "git annex fsck".

The fsck calls already prove the migrated data is accessible via the
builtin special remote, and TestEndToEnd covers the special remote
protocol with testremote, so the extra five full testremote runs
duplicated coverage at a cost of tens of seconds each on CI.
2026-08-02 18:25:09 +01:00
Nick Craig-Wood 01d32dbde5 build: fix intermittent CI failures by raising the test timeout to 20m
The cmd/gitannex end to end tests routinely take 230-530s and on slow
CI runners the package exceeds the go test default timeout of 10m.

Raise the per-package timeout to 20m in quicktest and racequicktest to
give slow runners headroom.
2026-08-02 18:25:09 +01:00
Nick Craig-Wood c59083f3b4 Add debaditya to contributors 2026-08-02 18:25:01 +01:00
Nick Craig-Wood a15551a838 Add Loi Nguyen to contributors 2026-08-02 18:25:01 +01:00
Nick Craig-Wood 40dbc9ba22 Add am-at-enrollvb to contributors 2026-08-02 18:25:01 +01:00
Nick Craig-Wood ce8caf0daa Add SillyZir to contributors 2026-08-02 18:25:01 +01:00
Nick Craig-Wood 49e41e7f0b Add acoeur to contributors 2026-08-02 18:25:01 +01:00